[Java][RestAssured] How to save application/octet-stream response as jpg image? - java

I want to download images from website using RestAssured. My code:
Response response = given()
.log().all()
.cookie(cookie)
.get(format(image_endpoint, "46581657"));
Endpoint returns status code 200 and image in "application/octet-stream" type. How can I save it as jpg file?
I have tried:
String bin = getImageResponse()
.prettyPrint();
saveFile("foto.jpg", bin); //this method only save string to file
But I cannot open jpg file. How can I save it?

MIME type application/octet-stream consists of bytes encoded in Base64. Use Base64 class for decoding.
private void saveFile(String path, String octetStream) throws IOException{
byte[] bytes = Base64.getDecoder().decode(octetStream);
try(FileOutputStream fos = new FileOutputStream(path)){
fos.write(bytes);
}
}
I know nothing about RestAssured, so maybe there is any way provided by framework.

Related

How to create an endpoint which takes a path, load the image and serve it to the client

I want to serve an image to a client by converting it to a byte but for some reason byteArrayOutputStream.toByteArray() is empty. I get a response status of 200 which means it is served. I looked at various documentations on reading an image file from a directory using BufferedImage and then converting BufferedImage to a byteArray from oracle https://docs.oracle.com/javase/tutorial/2d/images/loadimage.html and https://docs.oracle.com/javase/tutorial/2d/images/saveimage.html but for some reason byteArray is still empty
This controller
#GetMapping(path = "/get/image/{name}")
public ResponseEntity<byte[]> displayImage(String name) throws IOException {
String photoPathFromDatabase = productRepository.findPhotoByName(name);
Path path = Paths.get(photoPathFromDatabase);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
BufferedImage image = ImageIO.read(path.toFile()); // Reading the image from path or file
String fileType = Files.probeContentType(path.toFile().toPath()); // Getting the file type
ImageIO.write(image, fileType, byteArrayOutputStream); // convert from BufferedImage to byte array
byte[] bytes = byteArrayOutputStream.toByteArray();
return ResponseEntity
.ok()
.contentType(MediaType.valueOf(fileType))
.body(bytes);
}
After I debugged the method
You should read the bytes of the file directly, rather than use an excessive amount of methods from different classes. This can be done with the class java.nio.file.Files.
byte[] contentBytes = Files.readAllBytes(path); //Throws IOException
Probably the file extension is not getting set properly.
You can create a new method to get the file extension or you can use FilenameUtils.getExtension from Apache Commons IO.
public static Optional<String> getExtensionByStringHandling(String filename) {
return Optional.ofNullable(filename)
.filter(f -> f.contains("."))
.map(f -> f.substring(filename.lastIndexOf(".") + 1));
}
then change your ImageIO to take this file extention.
String fileExtention= getExtensionByStringHandling(file.getName()).orElseThrow(()->new RuntimeException("File extension not found"));
ImageIO.write(image, fileExtention, byteArrayOutputStream);

Sending xls via API with Java apache poi and React

I'm trying to send a xls file from my java spring server to react client.
Using default Apache POI constructors creates xlsx file, that's not good. In order to override it I have to create the file using FileOutputStream.
FileOutputStream outputStream = new FileOutputStream("file.xls");
But I cannot sent the file over the web. I've tried using the following answer: https://stackoverflow.com/a/54765335/10319765 I quote: "While downloading a file , your code needs to stream a file chunk by chunk - thats what Java streams are for."
return ResponseEntity.ok().contentLength(inputStreamWrapper.getByteCount())
.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
.cacheControl(CacheControl.noCache())
.header("Content-Disposition", "attachment; filename=" + "file.xls")
.body(new InputStreamResource(inputStreamWrapper.getByteArrayInputStream()));
so my controller is sending InputStreamResource.
How can I construct InputStreamResource using my FileOutputStream?
P.S this is my React client:
axios.get('/issues/export', { responseType: 'arraybuffer' }).then(response => {
if (response && !response.error) {
const blob = new Blob([response.payload.data], {type: 'application/vnd.ms-excel'});
saveAs(blob);
}
});
Source: https://stackoverflow.com/a/46331201/10319765
Edit:
I've managed to do that with a trick, right after I've written to the FileOutputStream I've opened a FileInputStream and returned the value.
FileOutputStream outputStream = new FileOutputStream("file.xls");
workbook.write(outputStream);
workbook.close();
final InputStream fileInputStream = new FileInputStream("file.xls");
return fileInputStream;
but now, the xls file returned as response to the client is corrupted and has weird characters inside:
The excel file should look the following (taken from my java server after sending it):
Issue solved. Eventually what I did in order to solve the corrupted xls file is to work with byte arrays. the controller looks exactly the same but now the return type is ResponseEntity<byte[]>. To convert the InputStream to byte array I've used IOUtils.toByteArray() method.
Client side code has also changed a bit because now the type is no longer responseType: 'arraybuffer' but 'blob'.
axios.get('/issues/export', { responseType: 'blob' }).then(response => {
if (response && !response.error) {
const blob = new Blob([response.payload.data]);
saveAs(blob);
}
});
That's all.

Spring boot file corrupted on download

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 = "iVBORw0KGgoAAAANSUhEUgAAALoAAAAyCAYAAADr7cFEAAAgAElEQVR4nO2df3idVZXvP99MzGTOye1Ne1NuH26pEJgKiLXlxJogKhRFYBwFfyDiNMjAiUKioMg4yFAeisAwWLxqU0qODJAq6r0KyI+K6FRBxxbmHIhMp3QQIpdCp1Ny29w+nPN0Mpl87x/vz3NykqYV7p3Rrj7pec/77nfttddee+211l57HzgIB+F3APRaIj+is3epxBXAO4BGoIh90/CmNQ+9lvUehINQC6+ZoLd39p4NvhPUXFWTmUB8HvjS8Mb+qncGh17+c1vrz1vS9tRrRddB+N2EhtcCaXtX7zzjWwzNJvzn8A832L4BWDT5Te2S2Ds4NNL4WtB1EH534TURdOwzJc0RIAkJhMJrIanR+Pza17oXtw0AHcDfDw6NtAAMPvny0sGhkdLgky/Pry0/ODTy2tB/EH7r4IA0Z3tnbwPiUPChoJ3gF4c3rhmPnhveIKg2jGqMJKGjpkC/1fZ9kvaG3/dgtiL2pgsNPjlyInD74NDI7cD13YvbDqQpVZAtlOYAzQaEAY0DO8v53P7gaAQOAQIMyeeucj63N1sotRjPCoZ+8Iygvu3lfMf+1JMxtCYWYZrF8bdxoGLzSqVn320IaGMWEd0GBUi37w8P/j3CfmvEIzovPsr4QeA54DGbXxn9rL2rtzMqI+llCNhtAoY59R3A9q56+I23Is0zfnBwaOTQ7iVztyKfj3X24NDIGYNDI2ElLDU+Cjh9f9tQDzKFYhP23wEvyX4J8xL4acP+jqBjgZdiPPASwecZALY/LRTXIfsl4ZdA+6d0zLmyX3JYR3xtvwSKrreBf41cygyUvpItFE8IB2J9lOZSwUtyRHPwZ/wf3pTcL0E/oqt3gdBPhE4DmmwQNAo6gR+lhH09MC6DgjLxJw5EXXBPvTqEOmV3yzoVODe8+w7jfsw6Q2uIZq3Q+YbzXw1tLnQGUnvwRVgCNEcxDTODwCMJB3SoDqVE10bXDuy5qJ6ILftDMA5NwYjm+C+sx1ITqE3oeIlPG/0M+ElmoNSRLZQmowxROaJLwkHv7Sdx//5g/zS6fZ3x/EBLBz2TaG232HytvfPiBmAIszbobHBoCBDdgAeQ7puilicMm4Bh8Prw3pDgIfCgYA/AeUvaKt2L2+6QPXHn0Mh1dw69fPbgkwdms2cKxQZMb9ym1KftfLZQapoxsnhAh2PaCb4QaXg/9UkiZDOvxyEOJ4PE8e2gztR1SEuDzYnAzwzdmYFiDUrHeNLTsDD/0WHGgtHedXGTxPsU9WI40NPjXaIDMX94Yz+Iz0hcDbwCRgKLMYk1wEeGN/ZP1Kune3Hb6HlL5nZ1L2k7snvx3C3hvRHg/YgKcP/g0MgygMGhlxuQ7hd8AfQd8KkHxAVzNHCSUtow8jEkjjM+aaaoEhyh8MYMclSgWvkqsYf3G5Q4++k6VXOfdF3BX7PgNqR31RCf4CGh87dBo8/c9rJakJtB1dpHVR8A84AXhjf2jwMr27t6b0YsBhplPzW8aU1d2zyClRu2NRh/Wuij4O8Ybr562QIMZwp9ISy2+M4nR460PS4xj3CCRZo34/akmyBdBDTWunSRuyjozRZKD8/EIbNdZaokeCbVWvXsQLRmfbw1ZVJFVO0eNwpuyQyU3ljpyY1NQd5vDcx8qhejhtE4Jp76l7iYTBg9n35teGP/K0JPABWko9u7emfto6ajgFXGS4FVgqPD+sdIZtZxiQmJcaAXtAX0beC7M25PCGGk5dygFUpaFJtmAutU21NFiaohssGJaa0R4QhvyjxKvbc/4Dp/wLttsuD/ZPsw4P2gh5L2QWpYHSVx0mTaav/+45suM9bowxv7J9q7egeBz1U9SClB4/VCO6NH7V29AN2YG4JwJGB2tXf23oC4ua75YiqSxoBmzBhyBUDmAcuXy1oC/lr3krmRFvr2qp9vv7c89m/HYeav3PDC1hXLFsyYAbbPkTQndpKVnqKMAgO6GZMHPr8vfEp/htq9npjEmvwABDx8EaXif2FbAPZWejoq4a1XgBezhdJ6wa3Yf4oUhg3DIKrdCTwMICs2pUKE/240e+gnHQpuCYnaA+wo5+vMRnVgf8NG14HfYbS0yqg0SHpB6FM1y/ofAm4zbkwcUc+RdBMw0d7Ve3NtGgDiRcMHwWcB9wi9ANC9ZO448KVaglZu2JZ55V/GfyBxImICa83KDds+s2LZYXV9gDSEzPtEIMuJQBq/IGuB00Fq1J0ZKF5X6enYMx1ORyN/Og/T6Rh72pzYP/Cki/r1lfO58WyhtMro4ziaxRXJ8X+N0aSC/nF/pcZStlA6A6jVIjvK+dy909GZLZQagHMIY/Qp2FLO5x6d5r1m4H3gjwUDUq1ITWF7x4DRbKH0C+CbwAPlfG7vVLjqCvrsvnVNmNOMTw4F4BHB+uHVy0fbO3vfo0CznYOYY/MKsB77muFNa16McLR39TaCrwE1Royr6fcrgQECrRM2rLjoL5/95yskzQJuLedzUdSFlRu2NQEXAm+3vVHSwIplh+01nCt4R9ApbjD0CReAzVM1OgZzIuK4WAsHnTwutBzxI+GmSMXZnifxAeCO6ZEmjmxSTdr2T7SmkzsH7oymrpPIVl0YEYwhmiNplsBWlXCkHdhaf8N2L+iMqnrxJmBaQTduFLoOc3jVWLTXApMEPTtQBOk0YBX42DTPItqAJoKFuTPBZ4I2ZwvFywwPV+osvE2y0Wf3rWsF7kd8X9KlwKWCe8D3t/YOzhre1D86vKn/CqQ3gI4UHDna0ZXf3dG1a3bvujgMZzMPgri0SE/RMblzgIVx4wqlVuBBSecQLK58L1soLU0x60pMP3AO6Cu2rwWQg1XGSANJNID25QeQLZRA9IIbkogIABuARw0/TnM3jD5cFGqn/YL6erY6Qn0gFkLsjKY+pranvTAIJlTXJvEP9WgLntU41XE6R3W5/aUzfrvOjJcdKDUargXuB45NnPbpawCOAz0IurbeolhVp7X2DmL7JvCpkcMZqRqbU0GrZvetA2B4Y//Y7lznyO5c1yLbP8B+DvF0a+/gl2f3rWuVGMcOzIdQ1SROXuTiONEmZpGt+SknqBHzrtTzsxOpMIgPhd++Cx6xIjeSTbafmJYvAbTbPi0St4g2m9uD6IpvS1ztOFbdQbA4NiVEmjqtXYOQdNo9TRzDKFx9QM6oq0MBge09GU+mUDoEdFNER4rHFZK1itS0olQY3aQHj9PFqobqvmjd97DIDBQbkFeB/oKUteFJ3Jt8HX5vFPwFeFW2UKyS7SrJl9QGnB01gdRFyMBzjS8HRkPqT0D6oVBLSgtcCnSOLjr+lNannngCODGOzzrSY4A9LOnZVPXPS66AMrGhKLYktDFMGIFRYEw+D7DilAUvrNyw7S0KTKk9wF1Xn7JgSlstxZQLpLCuSEDELnC4kKWHhLcT5PNEbG0ALgJ+MR3uOO6SiksTG/yR3Ru3kSqPfj8grVlTQn5iGElqBOYYcsIfAB1Sp4YbQTtifFUruNPUGdM8U53uFK31rsIZFi4FPl1bd/h1AnhB8GzIr4WC+aSUdQpzn+F/ZQulm6OQcLWKt9sIHYZqey8ysslgzQNGZ/eta7B9I3ZLYOsR2nwG6OR1TX8CXG74UewpRzKOx5E+M5rrHJt9fGeHxbH65ZbNY28+5iLEDVgthrUSyeqpuQxYgDjaeFjikujRimWHPQ/8ZX0mT4ZsodRiu7uKk4F2/HYUsajkc5VsoXgX5nOB8R5Sbj6QLRQvL+c7dtRBHZerYqBSch6reSKehsX300iPx4bjMWUbwQ1xj6eDJkrVGwyyb2CuL6eTvVxTLqI9Grp2OGiTZzMjOzSqHM6dsRykHRkvAq6NcSr2JLD1cwV7GDaV87kJCFazBSeCbsJeWlNdA3At5sfAUzDJGdWoRUWQibVOzFAB7EVE4cNWYFESJks6VQjjdw5v7B9o7+o92XBj4DDSABQNV77yh8f82PZXJPqEGhATr/vllpvHjzriMLf8AZV8R1XUZMUpC7au3LDtzUCb0EgUVQlsZv8p6KwQ//ds7qj05MaZEnym0PxIUByE1SaAO2v4cSfiUqDRmHC1MGPzcaYYWFG5Wmc0rccc1hvyKVmJ3R+IlYsSFyW8n9RbrZmjuoBvA+eVe3J1IlNR3k0wekQSfY/XCBQIbE10cxqotvlT6AHIDpRAXGc7U4cT35C4oDaMGMrHo9lC6Z1I37T5QBXbTQZxHfDHUGOj7+5fvkNmfdImJdQEtN6HCVY27XFJ47U2TrLSF3jzwxv7i7/euOYU4A+A7PDG/rf+euOaH4/P+s8nSOoDRc5gg6RLX/fs8x3llJBnC6VMZqD0yWyhVLjxuX/+3I3P7ZxYcUos5AC3ggqGMwynAQWJW6dyGoN31JvWKqGsbBY8XlN8M0HeTdLJQeMumioLMGp/2nauZ5aIZPHmgCCUsqieqLvSmaLRAEgGQSyy5wAPZgeKVaHC2BZW2oypNjWSuS2SjRnSP8mxTdfLsYbTohBvMvvxBJCfLlYehhSXS4Hmjn2IAMdp2ULpaKi3Mio+hRlKEoYcvfgUcMnu/uURpXuwN8SeSTohKrj+fg3mcSDT3nVx6PmzyHZD4lAZ243Gx0UvZAaKGcyPJG6xuRC4EdiYLRQPjXHAhdU5U8bwccPiupyxl9ruSMiMrc3ba5f4y/kctm9zqn1hHyzAvK8u/gifqwUj/TQ1O5NCvX8gJaZJytGLTQuTel5tGIXXp1l6LFsoHZ/gJHYvqx3QRNlFz2stsekgTm5LqqlKdJN4n1LWhYh58vnpYuMRlPO5CuYKzIRI6WbTCH4v1Imj7169fMfsvnVvx3QLTg4Z+hPMHbv7l1dCTdmwO58bn9237jICgTqqOoOIr9uJN9/e1bsAuI3Aphpr7+pdu/vfxh/k9xonlB5sgfmwJaFGf4I4AdIawEcZXQZcBiwONJmrpnGgAXMcgUaoAouLhFJ5LQaogP5HPSZKuhe4iSgv3XGC2kXZQunuevkvsaU37cpoTdkDgCh3JelYY+l5iUpYZ4PtVuAQQUM8C4S2uNA8w/ezA6W3lHtyO6KV0QB3ZBulBmR07cisAWvfkq6IF5Gp5uomG7+tKucnQL8TNJItlBZF5mBsFhKtTKScEbxTZg/QGj8Jir4N+FKVoGcLpTbgqDEYAdaW87k1qWdN2ULpWgInrikzUFw/Jj7f9Munu4BP2u6S9IrE/wTfO9rfPQ5wRNfFDQ5s35NCVM2CP2sdKv7T7uPfutbwSQKzZQJYTdp8EG+OZwrSQuFov+nzsf0XlYocKgUrqmnIFEqHYH8oYVTM8WbsXwYLFdSqHhCt1ZIJQssINllsSdeR+IiJulX6xbhUzeWBpAKk1bkiJe/lNr9I5ak3254HfMjS5cJtKaWBYD7SNZlC8RNVBKX0QBzvjnlbXe/MCHWsJOKvSYGjqr4Fzw9BfjJuZszHmv5OfVRNMwm6dgg1erZQwvanbV8j0QoaA+7LDBTzlZ6O0fCFG4DPxjYc+lNgwdibjz29nM99cco2mnmST4w0bjIWfZakk8HfAo7G3ox4fPfq7tg+l/nHoLKIqYruPxMW+QXoUQJHlxTnHwVPCgEKPo7U4lgIY840WG7DiSZIhldIbaTJrVAb0mC4KFsofSqt1WOzJL2iiIO8lOreCO3hSEvtP9iKBSdY8wgw1TiZFWAY+KtsofSAzSNAW+wYBpGacyR9PuJxxOpoZTRxRklmzvD7zLIuHQwWp9oazg6ZQqlRqdSAus68J9n08WwZ4YrbUp2uCeFGnUijn4a0CmgMRaXJ5kOSRoFo48Enow5MHBKWKdBq8fEUs/vWHQu+CNQK3O+nnnhUY/8yJgVbxeKGWpXdq5dPAD8P/5jdt47WvnUtgvHdq5fvBd9hkRc6LmUmbhd8GeIcjrOMVyFOC3GvB64o5zuqHJjsQKmRunktEU+CaEhaSVUzPBxkSulocy7iKqJ1BaZQcladm9GgOEC7pQ62yESYCsr53JbsQHEN0or0exazwItjkXZI8qR0Y6okrtp82AdtqXfTQ15BfHyCiPRooKXKpfo+6Zsa2lxLW8LycUjs449hGmMnJipszg4Ta5ptNxM5cI5HVQOp0Ti7b3CR7Y2GPtt/Yvyt//OmJReC7oqICZ2QceSvRe+19q5jdt+6pbZ/KPyc7V+19g4WXvfU082gk4GVgvuwbwbeVu7JPTu7b13D7L51maahLXsq+Y7zMa8HXl/uyV1QzufiDMoUr0/DwTQWNS6RiSQbJW2hpHy6hDFORNMwx3bVVrv4vbS8yam0X8fCFGM5UFC6rpmm++qx+jVqfhQGjRzapP01s1BSPdgz2H3lBpumyMGNrRebcj43YbwrXVM8K6bL1nzW0lPb6tSYH4FEo7ckU1VQLFy5a8Q0lXtye7KF0uPgYPk7iv+IHVQlT+kSqSpDrQFxSfmII9+Yff65X2P+GLHH5iuSYmdVuBP0Q6VyVCQuBJb+/i+3vG336uVXR/dn961r+P2+decAl2DakUdn9627m6eevmH36uV1MwuzhSLGvUm8OtqoEbJqClsz0T+TpsPw2gh9IlsoDZTzSdxe4bN4Fqj6P5o20vpwxsZuNX3RnB4740yr0cOaGtNiG/V37bSftuNTMDZJ5MW8bKHEtJtSTLPEnEn0J7b/VsSiKtYGWv508Ei1kAdX0bUmDYHUswDhHogF3T+yOTPq98QW8+PlJC31AtD92O3hyN8FuqCcz8XTNnBIpLkkRVqsZey/zG3852999nrg+trGzu5bh+EGwaz0wkqIZZGgB7g5Kgt8IfAl1BBqiEMwf444aXbfulN2r15eqa3DaKHwqZPzq/046JK0ZRFp27ijHdmsAvsq4IygQFx4kQMfYUO6xiq1Lf7frYxOo9GzhRKYtyf0pZCJ7ZjDp18ZZTReRIyf0Sa8AJjk/McgLQI3T7My+hMcpJ6kFE8DqBO0sjKDnV3ZQqlRpqFOotgYhIJu+LrEe0DvC50TBC+CeqPS5XxuS7ZQepPFSULN4EfL+dxIDdIfIN6bttskPYG9o72rF+yFSAtt75D0xPDG/gkHKQSLqizjamF8O6GgGxYKrlTgCCaaMhiYnYg+4K/q8OEioCFZMImdolvL+dymfXIxhEyh+DWhM5LGxVqhN1sobSjnc/WdqarJ/zVeGZ0W3IHoIUVfoIy0V3gzcEKg3QP6Jq+M8quI/mhlFGhCOhP46pS1wkdTGnaSMlGwUf4m2y01nLicIAV42iMKs4VSq+FJxOGxfgrwjxq/HtjTCFDJd4xlCqWzsE+VtBS8Hem7kbZe+TcvNCCdALTa/unVpyx4JV1RplBsFVo0Nvav977u6V8dQ6CFmyQ9brN8TmnTPKTbkU6Np0t7yxFdFy8fFVsIDgqaQhsp1tCyT0VqjmK4TJ5q3z+7b91f7V69PKFtoDQL6KZK1ARilH3kUU+iBDYYhjHtcaKWQNIZ4HZgOG2MhO9AHTF+NVdGIyyuMV2yhVKj7VkSR4M+SBBQyKTaEwozG7B2xp6KaukLr+xNkcZ0XA6AKzMDpbsrPbl4P0KKhhMcLOBVW32pL+V8bnumUPyGpE+amAQMLYL7MwPFP670dNQV9uxAsRX8PaHDY38qtmJ8V7RRJo6jV4JkmYfCvxiu+ZttDYjbwd0hD7eu3LDtnSuWHbYzqKh0guH7tttoet0r/7romI82PfX0VeAMZsecJx5rAh4BL60iIojW/GB26bHc7lzneuOPE2qoxGkRpM5/sWgJ6HdiGkVaIbAvWurotnMwcyIGRvpVcB8w7UbtWijnO8ayheI3nIpahM1pxrqAYDNJlcaarGlNrWU585yRFEQro6FmT5Ij9ZNsoZREMVCD6xxAlIivx0HXlntyZArFlAmXdFQ8H0mbMNsVbotM0X6I4GfZQuky4KcEp6vNM/6A4RqCtZMqB3OST2CuQZwJzFOCF8MCpI3ZgdJqxDcxzxLsFZ5v+wykzxvPh9RAEhiPWroxuhUzYOWGbQ0E+zuXEziZ16xYdtgziIXB/Sh8xdFAN9G2NnGNcFvYoS0WN/zLomPfXOkJZoPWzt4zJJZGDkJkD4eMPAS4BLhC6Hjig0fjCeyvgbsT+vVE0k1JycgcAYq7VydJidlCqRHziVQyUxx7Nr693k6UfYHNncAXEI1Vgiy6s4XSDRF11eZJGqp1vKYeEfuERLZT9IXOplP3a7VpzWxzLcEuocAfUSSMSR5NBOV8rpItlG4h2BgRzggxssMN3xPsNYyDmyRVRWSqNXr1yC73dOzIFornC77vwBpIv5NB/Bn255D2GiZkmieFrBOYELqsnM/FfkMq18XvA25DLAPOBd+zcsO2ZjlaOoYgZ8JQnRSfREqCYi2BIxE37q3JOK6G8E7H7tXLdwBvJ1jWv1v4LuDDQD6MtUe1/RT4abJXPxwwQS7HHmBVTRUnIB8fGxNhbNR4q9C0OeVTgngevCFWZ3HSjOeDz4xno1Tuj6pyTZx8hhlY6ZlpxhDFedPtcniOQVhnlK8U0RGVC0V4HPgi8MXozMcogyLiqUJ8NUP1q8abo3rjjTRhWexm2S2CJlLPangV9Vktcx8yysuMpfGm8qcawBnhFnBjbZnw+wRB0OOONOaUoOvdBDkiER+PBg4HtiLd7YgT8LzxN+K3UH9kYyMmbG5RGKQP75WTzoC4oxMTpQKwe/XyPbv7l9+8e/XyD84uPfax2cWNG2YXN53Y3tW7rL2rd157Zy+7V3ePgT8KWi80EWkeScNIHyS1HB+s9tILqWPVpNDx0zdnunu8FoL0UN0eTI9KLT4JO3B6E16Fz0WdldHg2Lt6CzMzAlW3K7anQ/OP6A/ie05s+qccpK9eFeV3R+ViGtM4U1DO5/bI+gjohYif6fZGbQrQhfdgJ9L6dLnYz6rGjWAQ8UFJO6Ny8WdUR2T6qbpfCUymXuDqqnZRnb34y5ohNgLsCFNiPyrzftvnSbz16mULYqfjmJbf/8bvwbtBVwJ/JPSlmpjqQ8B4MhWFnybYKWQeTBdu77y4CfwF4FeIR7D/BngOcWt7V++s3au7dxB00hKkD4NPBt40unr5j9NOKHC4xHtrtYZhDHMXvwnI94b8Cb5GbZOWCjomia1TQpdGk/r/N4coHSDZBhfSNK5g59VW7K+DTge9pZLveKhe7DvyLxJBmgzlntwW4GSCjQ0TtQ54SpAngJ9KeifmiXQ++lSWWjmfo5zveACcA+7AVIgHTqq11bTtBb4r6a3lno61tUIO1dmLg8hvxjrbsAtxyYplh40CrFh22Njg0Mh94CaHcUmAlRu2zbN9O4dwqNDlK0457OFJlJsi0lpMX+gkkAq/PWr7jqhoe2cv4BtsPhu9HNqbGdk9oAXtXb3vH+5fPkYQcpou7DQC5BKnK2RQQP/wNO/tE4Jce+eCrXghpbFDqVHMMajaybT9Yvi5VlLid5jGMHY9zUaRyWBzt2BT4rUlnykhGMfsBfYgdlV69uGTiLVyKhIVSX00Y6egnM8NZwql0wXvMHwkHOCHEijPHUAR+A6wIUjVKH7N1nfirjcEK6L1oZzveBE4P1soXSNzJuKdso8mPHefIJDwDOYR8H1Iz063aDVpyF67YVvzf2ttnvV7DYwJRrsXz2VwaKQJWAd02twqfH33krms3LDtGmBFyJTNK0457E31KmnvvLgR6UICx3MBeBfoLsx1w5v649XMI7ouPk7oSXBjRJpjT8rRATsfHt7Yv98nch2E322YFHZ6/Zw/+ABwG2bMgUP4sOFUwdmhtrgaNECgMbdFuc3A9qkqGd60ZhxY297VuxZoBo3VP6VLZyAakwWL4HbVsoU5iwM4eu4g/GaQLZROA1rK+dxvzPvsQLEFaEaM7M+PH/wmUG87WB5oBpolzgMeFjwPjBMcVr/dJlrEuUNiAjQfvHZflRm3YZ0pcWR7V+8/AQ8Mb+yPzQiJuVBtu8a+eZzi6d/8MPSDcCDwfgLTZMaCni2UOoALwJdUZZNKVwNnGo5hP022A4V6gv4D4CTEBOZHAN2L2zYPDr18stEJMg8hjwGsWHbY+ODQyCBwnPGUR7W1d/Vi+1yZW1AYjgzMkFXtXRdfD1wzvHHNBPCPyVth5D3S6rHdqWc4CP8foDYaPyOYD5xNsCMsHeW6lSDmvs9jA18tmCToNl8SPIq8FzQU3e9ePPfng0Mjr2B+JigODr38nu7Fc8fB/TYXSvwUOGWKek4Cbif5lYzAKbUaQSuM/zfwVfC9oBss2uQkNzqVlTeGdOeryoHfEcgWSvONPy44BjMK/K2l71bCMGu2UDrU9oUSb8DsQLqznM/Fzr5T/wfli502Cys9HYPxvYHSscYnSRowtIHPwjQbLs0MFMcltpbzHfcBbbYXVno6NqXoOxR8IfAGYCfotnI+F2fGZgrFd2FmSXrG9nnAPIlHQH8dRVmyhWKDg1Pe/ghowfxK0t3lfG7zpM3R5y1pm+he0rbJ1mbEtXcOjdyQ+jnEVosWrEOJE8K0UFIDqePl0hBoc66W1BTHQqMwU7yOpM+3d17cMrxxzQjmAkylNpPRYgLpKgJv/iDsBwRCxGOYt4JKRnuRrlV4IFR2oNgOPIb0HtAwwU/c/G22UIp/WCH6mZ4IjN4l6VNVFYnFCsLMjZiM0QKkRsEbJb0xMHEBvExSfC5PtlBqBx4zOh0zDDoceKy6fp0luNVwP6gNaDDqt+lLEfBnoNswo4K/F8oRruJOeZquxALsL4TL03cCW4FHZecsduLAthJ8Any+p/hNIqBVYnG9iS8K/QW5EzoKGALuQ7wdcyWwVNAYbLPTl4GHJp2+exBmAu/CzkhaHiXqZQulq4jWUQKb+UXBKeV8bm+mUGoQvsXmy9lC6U3lfG6CJO06eAWqvicPgnNyKj254Wyh9BXwIqR8OZ+Lk/OCmbrq3auwtwMnl3s69mYLpQbb/cCq7EBpSTk8o8fwAoxYMDAAAAPASURBVPjdlZ6OXeH2zzHgw9lC6avhiQ3LJf11uafjiqCNRQh/IXC6AzNfQLoa+3oU7NHsXtw20b1k7hDmvRJ/N/jkSEv34rZngB8K3To4NDLZUQx2ITVMtTKqZPWgCWB4Uz+/3rjmCUkftP2HiCON3j28sX/9VD8HcxCmB8OzSBmbW7KF4pnZgdLhwN5yPvdK8NzLgHuioyXCBL9vSVoIREeLTFpAmnpBt2blYprH2UKpwYFPeE+lp2MvQDmfm5D0HaTjEPGvmEjaXsl37ArLIOkfJFrBDeHzrdjdmULpc5lCqdMwq5zv2AnTaPTuxW1RLsQkEBrC3EPy25+7CHYa1TuDYxR4VtLx4bsBDqeYIEZtp89hJNTc+zzT4yDsGxScFfkxiYuAAsEusEezhdJHyvncLlCr8WjNW6MEuSXTnExcK8SRwTnVumfyWioBoAnIYNUuHoX0hPVPOaiqHlyEdKVM3uIaoUpmoHhFpafj6wf0K27dS9oe717StjIcDHQvnvtU9+K25cDlg0Mj56TLDm9aM2F7FdEG2Fijp/7g67/ex28bHYQDh2BZPffdcj53CugI4HQH5xV2Awi/KHNE+h2bwwlCyskZk1U2OhOetF80EN/aExBqBT+YxeN7ewUjiCOrCtmHg8cd1V93i6CrzKdyPreznM9dgjhG8AbsuxGrsgOlplf3h1LtB5Fqdx0h9G3wMaA/V/zDscZoAvtu4OpXlY6DUAXZQum0cBtcsZzPvZItFIuSKrZD21ffkvhEtlCKfLE5BLt7fhxo/ABq8g1fQGrPFkoLCX4qcwHwsahkCLsUnLTcni2UNgNN5XxuzCmNXs7nyBaK3yI4e/528FZQq83lMg871Oz1TktIUq4DyBRKnxXcgb0L6UWkvxfBceOvqqB3L5lbe3YhAMOb+ifaO3uvQjxIwIx2rJ0S9yA9cND2fs1hHuIezPOZgeJ2ggjZM5IGAQRfsv0Wib+zeRaYj9iuWHDBeCId95a5z/LlmBKwA9SK2GSCY+HCl4oWmwWP2H6e8CxFoYmqxGXz34XfgihhthofLmk78LFKnKBlcHXcXWLC9kSyydrnA1cbnsJuRBwt85lyT8fYlJbPQfjtgmyheChWR7hL61mgmM7yC53C4wULsXdY+nkllcqcLZQONW6s5DvizQzZgVLG8jKhJuBRzDhinvEz0WnImYFShqBMMzBUzueezRSKbUKt5Xzu2XT9wPFAtKf45+lU6kyheKigsZyuv1BqA7dCkNAVbrQ5HtFOkP69KTr65P8CEtHnF7Z82nMAAAAASUVORK5CYIIA";
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);
}

Displaying PDF from base64 string with Spring/Java

I have a PDF saved as a base 64 CLOB in a database.
As a functional test, I'm just trying to get it to display in my browser. I made a new endpoint in my controller and just put the base64 String into the controller, without even getting the PDF from the database, that looks like this:
#RequestMapping(value = "/output.pdf", method = RequestMethod.GET, produces = "application/pdf")
public void makePDF(HttpServletResponse response) throws Exception {
String value = "R04jArrrw45jNH6bV02="; //<--This is longer, but I shortened it for this question
byte[] imageByte = value.getBytes();
response.setContentType("application/pdf");
response.setContentLength(imageBytes.length);
response.getOutputStream().write(imageBytes);
} catch (Exception e) {
e.printStackTrace();
}
}
Whenever I hit the endpoint, I get a Failed to load PDF document message. I can't figure out why.
I'm pretty new to this, so I'm having trouble figuring out what my next steps are. How do I get the PDF to display in the web browser?
EDIT
I was able to get this working, by using modifying my method to the following:
#RequestMapping(value = "/output.pdf", method = RequestMethod.GET, produces = "application/pdf")
public void makePDF(HttpServletResponse response) throws Exception {
try {
String value = "R04jArrrw45jNH6bV02="; //<--This is longer, but I shortened it for this question
byte[] image = Base64.decodeBase64(value.getBytes());
Document document = new Document();
document.setPageSize(PageSize.LETTER);
PdfWriter.getInstance(document, response.getOutputStream());
Image labelImage = Image.getInstance(image);
labelImage.setAlignment(Image.TOP);
labelImage.scalePercent(new Float("35"));
document.open();
document.add(labelImage);
response.setContentType("application/pdf");
response.setContentLength(imageBytes.length);
response.getOutputStream().write(image);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Trying to understand exactly what I'm doing here, and why it worked. Obviously has something to do with Base64 decoding, and using the Document object.
Stack Overflow post Blob vs Clob and why you should not store binary data in Clobs
PDF has a general text-based structure. However, PDF files can contain non-ASCII ("binary") data and should always be considered binary files, - sorry unable to find a source of truth link for this.
There is potential for a lossy encoding of data, and decoding encoded Base-64 in that case.
Decode using Base64 before you stream it out
Base64.decode(base64String, Base64.NO_WRAP)

Convert byteArray to XSSFWorkbook using Apache POI

I am using Apache POI and I am trying to send a xlsx file as HTTP request and get it back as response. I am using jayway restassured for making HTTP requests.
Here is the part of the code where I send the request
File file = new File("path");
String response = given().multipart(file).when().post("URL").getBody().asString();
byte[] bytes = response.getBytes("ISO-8859-1");
InputStream stream = new ByteArrayOutputStream(bytes);
try
{
XSSFWorkbook workbook = new XSSFWorkbook(stream);
}
catch(Exception e){
e.printStackTrace();
}
Here is the code where the response is generated for the request
XSSFWorkbook workBook; //this workBook has the workbook sent as HTTP request
//code to make changes in workBook
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
workBook.write(outStream);
byte[] byteArray = outStream.toByteArray();
String responseBody = new String(byteArray, "ISO-8859-1");
context.response().putHeader("Content-Type", "multipart/form-data").setStatusCode(200).end(responseBody);
So, what I am trying to do is send a xlsx file as request make some changes and get it back as a string response, convert it back to xssfworkbook. When converting back I get error in the following line-
XSSFWorkbook workbook = new XSSFWorkbook(stream);
The error I get is
java.util.zip.ZipException: invalid code lengths set
You cannot simply send the byte-array as ISO-8859-1 encoded text the way you attempt.
There will be special characters that might get replaced/truncated/modified.
Currently you mix binary data and a text-only channel (HTTP). You will need to do it differently, either use a binary data transfer and not convert it to String or use some binary-to-text representation, see e.g. https://en.wikipedia.org/wiki/Binary-to-text_encoding, the most common one being Base64
Use
InputStream stream = new ByteArrayInputStream(bytes);

Categories