I am forming a pdf file. When generating a file locally in Idea - pdf is generated correctly. And if you send this file to MiniO S3 - instead of Russian letters, the symbols '#' are generated
I myself tried to specify the encoding explicitly via metadata.setContentType ("application / pdf; charset = utf-8"); Does not help :-(
Now I'm more inclined to add fonts. Tell me how I can add this to the existing code.
Thank you in advance!
#SneakyThrows
public byte[] createDocument(PaymentInstructionModel model) {
WordprocessingMLPackage word = Docx4J.load(new ClassPathResource("template.docx").getInputStream());
MainDocumentPart mainDocumentPart = word.getMainDocumentPart();
Map<String, String> variables = objectMapper.convertValue(model, new TypeReference<>() {});
mainDocumentPart.variableReplace(variables);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Docx4J.toPDF(word, os);
return os.toByteArray();
}
byte[] document = documentService.createDocument(model);
String key = String.format("%s/%d-%d-%d_Платёж_№%s.pdf",
event.getPaymentNumber(),
event.getPaymentDate().getYear(),
event.getPaymentDate().getMonthValue(),
event.getPaymentDate().getDayOfMonth(),
event.getPaymentNumber());
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(document.length);
amazonS3.putObject(S3Buckets.CLIENT_PAYMENT_PDF_BUCKET, key, new ByteArrayInputStream(document), metadata);
try this method:
public String escapeHtml(String value) {
if (value == null) {
return "";
} else {
return value
.replaceAll("\u001F", "")
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll("\"", """);
}
}
Related
I have a rest api which allows me to pass multiple IDS to a resource to download records from specific table and zip it. MSSQL is the backend mastering messages.
So when a ID is passed as param, it calls the database table to return the message data. Below is the code:
#GetMapping("message/{ids}")
public void downloadmessage(#PathVariable Long[] ids, HttpServletResponse response) throws Exception {
List<MultiplemessageID> multiplemessageID = auditRepository.findbyId(ids);
String xml = new ObjectMapper().writeValueAsString(MultiplemessageID);
String fileName = "message.zip";
String xml_name = "message.xml";
byte[] data = xml.getBytes();
byte[] bytes;
try (ByteOutputStream bout = new ByteOutputStream(); ZipOutputStream zout = new ZipOutputStream(bout)) {
for (Long id : ids) {
zout.setLevel(1);
ZipEntry ze = new ZipEntry(xml_name);
ze.setSize(data.length);
ze.setTime(System.currentTimeMillis());
zout.putNextEntry(ze);
zout.write(data);
zout.closeEntry();
}
bytes = bout.getBytes();
}
response.setContentType("application/zip");
response.setContentLength(bytes.length);
response.setHeader("Content-Disposition", "attachment; " + String.format("filename=" + fileName));
ServletOutputStream outputStream = response.getOutputStream();
FileCopyUtils.copy(bytes, outputStream);
outputStream.close();
}
Message on the database has the following structure:
MSG_ID C_ID NAME INSERT_TIMESTAMP MSG CONF F_NAME POS ID INB HEADERS
0011d540 EDW,WSO2,AS400 invoicetoedw 2019-08-29 23:59:13 <invoice>100923084207</invoice> [iden1:SMTP, iden2:SAP, service:invoicetoedw, clients:EDW,WSO2,AS400, file.path:/c:/nfs/store/invoicetoedw/output, rqst.message.format:XML,] p3_pfi_1 Pre 101 MES_P3_IN [clients:EDW,WSO2,AS400, UniqueName:Domain]
My file name should be like: part of header name + _input parameterId[0]
i.e. Domain_1
File name for multiple paramter (1,2,3,4)will be like
Domain_1
Domain_2
Domain_3
Domain_4
Below code retrieves the part of file name as string from the header.
private static String serviceNameHeadersToMap(String headers) {
String sHeaders = headers.replace("[", "");
sHeaders = sHeaders.replace("]", "");
String res = Arrays.stream(sHeaders.split(", "))
.filter(s->s.contains("serviceNameIdentifier"))
.findFirst()
.map(name->name.split(":")[1])
.orElse("Not Present");
return res;
I need to create a file name with header and input parameter. Once the file name is set, I would like individual records downloaded with correct file name and zipped.
Zip file name is message.zip. When unzipped it should contain individual files like Domain_1.xml, Domain_2.xml, Domain_3.xml, Domain_4.xml etc...
How do I achieve this? Please advise. I need some guidance for the limited knowledge on java I have. Thank you.
I have different types of files stored and I have a controller to download the files. The files are stored in base64 and I'm trying to download the file and the file seems to be corrupted althought the download works. I could really use some pointers to fix my problem.
Here is what I have so far.
#GetMapping("/attachments")
public ResponseEntity<InputStreamResource> getAttachment() {
String file = "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";
String decoded = new String(Base64.decodeBase64(file.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Encoding", "UTF-8");
headers.add(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=" + fileName);
InputStream targetStream = IOUtils.toInputStream(decoded, "UTF-8");
return ResponseEntity.ok().headers(headers).contentLength(decoded.length())
.contentType(MediaType.parseMediaType("application/octet-stream")).body(new InputStreamResource(targetStream));
}
The base 64 encoded file is a PNG file. PNG files are binary files and cannot be represented as string and are not UTF-8 encoded. Just return the byte array.
#GetMapping("/attachments")
public ResponseEntity<byte[]> getAttachment() {
String file = "iVBORw0KG ... 5CYIIA";
byte[] decoded = Base64.getDecoder().decode(file);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
ContentDisposition contentDisposition = ContentDisposition.builder("attachment")
.filename(fileName).build();
headers.setContentDisposition(contentDisposition);
return ResponseEntity.ok().headers(headers)
.contentLength(decoded.length)
.body(decoded);
}
I would like to read a hdfs folder containing avro files with spark . Then I would like to deserialize the avro events contained in these files. I would like to do it without the com.databrics library (or any other that allow to do it easely).
The problem is that I have difficulties with the deserialization.
I assume that my avro file is compressed with snappy because at the begining of the file (just after the schema), I have
avro.codecsnappy
written. Then it's followed by readable or unreadable charaters.
My first attempt to deserialize the avro event is the following :
public static String deserialize(String message) throws IOException {
Schema.Parser schemaParser = new Schema.Parser();
Schema avroSchema = schemaParser.parse(defaultFlumeAvroSchema);
DatumReader<GenericRecord> specificDatumReader = new SpecificDatumReader<GenericRecord>(avroSchema);
byte[] messageBytes = message.getBytes();
Decoder decoder = DecoderFactory.get().binaryDecoder(messageBytes, null);
GenericRecord genericRecord = specificDatumReader.read(null, decoder);
return genericRecord.toString();
}
This function works when I want to deserialise an avro file that doesn't have the avro.codecsbappy in it. When it's the case I have the error :
Malformed data : length is negative : -50
So I tried another way of doing it which is :
private static void deserialize2(String path) throws IOException {
DatumReader<GenericRecord> reader = new GenericDatumReader<>();
DataFileReader<GenericRecord> fileReader =
new DataFileReader<>(new File(path), reader);
System.out.println(fileReader.getSchema().toString());
GenericRecord record = new GenericData.Record(fileReader.getSchema());
int numEvents = 0;
while (fileReader.hasNext()) {
fileReader.next(record);
ByteBuffer body = (ByteBuffer) record.get("body");
CharsetDecoder decoder = Charsets.UTF_8.newDecoder();
System.out.println("Positon of the index " + body.position());
System.out.println("Size of the array : " + body.array().length);
String bodyStr = decoder.decode(body).toString();
System.out.println("THE BODY STRING ---> " bodyStr);
numEvents++;
}
fileReader.close();
}
and it returns the follwing output :
Positon of the index 0
Size of the array : 127482
THE BODY STRING --->
I can see that the array isn't empty but it just return an empty string.
How can I proceed ?
Use this when converting to string:
String bodyStr = new String(body.array());
System.out.println("THE BODY STRING ---> " + bodyStr);
Source: https://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/
Well, it seems that you are on a good way. However, your ByteBuffer might not have a proper byte[] array to decode, so let's try the following instead:
byte[] bytes = new byte[body.remaining()];
buffer.get(bytes);
String result = new String(bytes, "UTF-8"); // Maybe you need to change charset
This should work, you have shown in your question that ByteBuffer contains actual data, as given in the code example you might have to change the charset.
List of charsets: https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html
Also usful: https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html
Is there a way to check if an attachment is already present in the PDF document while creating the document (not after the document is saved to disk)? While parsing a XML to PDF I came across over multiple attachments which have the same content (Base64 String from XML > byte[]) and the same name. Currently the attachments are added multiple times, but I want to check if an attachment (with the same content or name) already exists (PdfWriter API?) and if YES, only a new Annotation should be created to the existing attachment.
NOTE: the check should happen while creating the PDF, not with a PdfReader and an existing PDF
EDIT:
Thanks to #Bruno Lowagie I got it working:
protected HashMap<String, PdfFileSpecification> cache = new HashMap<>();
private final byte[] BUFFER = new byte[1024];
public PdfFileSpecification getPdfFileSpecification(final PdfWriter pdfWriter, final String name, final byte[] data) throws IOException {
String hash = createMD5Hash(data);
PdfFileSpecification pdfFileSpecification = cache.get(hash);
if (pdfFileSpecification == null) {
pdfFileSpecification = PdfFileSpecification.fileEmbedded(pdfWriter, null, name, data);
cache.put(hash, pdfFileSpecification);
return pdfFileSpecification;
}
System.out.println(String.format("Name: %s Hash: %s", name, hash));
return pdfFileSpecification;
}
private String createMD5Hash(final byte[] data) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
return null;
}
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
try {
int i;
while ((i = byteArrayInputStream.read(BUFFER)) != -1) {
messageDigest.update(BUFFER, 0, i);
}
byteArrayInputStream.close();
} catch (IOException e) {
return null;
}
byte[] mdbytes = messageDigest.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
So every time I have to deal with a new attachment I do it like this:
PdfFileSpecification fs = getPdfFileSpecification(pdfWriter, name, data)
PdfAnnotation an = PdfAnnotation.createFileAttachment(pdfWriter, rectangle, name, fs);
Allow me to take your code and introduce some pseudo code to show you how I would do this:
protected Map<String, PdfFileSpecification> cache =
new HashMap<String, PdfFileSpecification>();
public void cellLayout(final PdfPCell pdfPCell, final Rectangle rectangle, final PdfContentByte[] pdfContentBytes) {
String hasheddata = createHash(attachment);
PdfFileSpecification fs = cache.get(hasheddata);
if (fs == null) {
fs = PdfFileSpecification.fileEmbedded(writer, null, displayname, attachment);
cache.put(hasheddata, fs);
}
PdfAnnotation an = PdfAnnotation.createFileAttachment(writer, rectangle, displayname, fs);
writer.addAnnotation(an);
}
This code won't compile because I left out some parts that aren't relevant to the problem. I only kept the stuff that explains the concept of creating the cache for the file specifications.
I create a hash of the attachment bytes to save memory. You will have to implement the createHash() method using the hashing algorithm of your choice. Before I create a new FileSpecification that will write bytes to the PdfWriter, I check if I can't reuse an already existing file specification. If one exists, I reuse it in an annotation. If it doesn't exist I create a new file specification.
I am sending an image after base64 encoding from my JSP to a servlet using AJAX. At the servlet side, I am trying to decode and save it to either a file or render to a browser.
I am getting an empty image. Here is my servlet side code
String imageStr = request.getParameter("image");
byte[] decoded = Base64.decodeBase64(imageStr);
String path = "D:\\myImage.png";
try {
OutputStream out1 = new BufferedOutputStream(new FileOutputStream(path));
out1.write(decoded);
} finally {
}
I get a the image, but its empty.
Try closing the stream, it should flush all buffered data:
String imageStr = request.getParameter("image");
byte[] decoded = Base64.decodeBase64(imageStr);
String path = "D:\\myImage.png";
OutputStream out1 = null;
try {
out1 = new BufferedOutputStream(new FileOutputStream(path));
out1.write(decoded);
} finally {
if (out1 != null) {
*out1.close();*
}
}
And make sure the decoded array really contains some data.