Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring returning image as ResponseEntity<byte[]> - image corrupt

I am working on a spring 3.2.7 app and it sends signatures stored in the database as base64 string back to the users browser via a spring controller which outputs the byte array ResponseEntity.

The image is always corrupted and I havent worked on this part of the system as I double checked in svn and the controller has not been touched since the branch I am working on was created.

I am able to convert the base64 string to an image on my desktop and I am also able to the convert the byte array returned to browser into an image before spring steps in.

Below is my code, this was apparently working before so perhaps there is some config change that could cause this?

  @RequestMapping(value = "/submissions/signature/{type}/{id}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<byte[]> getSignature(@PathVariable String type, @PathVariable Integer id) throws Exception {
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   String base64 = ... gets from db

   byte[] bytes = Base64.decodeBase64(base64);

    BufferedImage bi = ImageIO.read(new ByteArrayInputStream(bytes));
    ImageIO.write(bi, "png", baos);

    HttpHeaders headers = new HttpHeaders();
    headers.setLastModified(Calendar.getInstance().getTime().getTime());
    headers.setCacheControl("no-cache");
    headers.setContentType(MediaType.IMAGE_PNG);
    headers.setContentLength(baos.toByteArray().length);

    //Image as base64 string is ok in converter
    System.out.println("BASE 64 IMAGE IS: " + base64);
    //This image is created ok on desktop
    FileOutputStream fos = new FileOutputStream("C:\\Users\\p\\Desktop\\test_signature.png");
    fos.write(bytes);
    fos.close();
    //This image is created ok on desktop
    FileOutputStream fos3 = new FileOutputStream("C:\\Users\\p\\Desktop\\test_signature_baos.png");
    fos3.write(bytes);
    fos3.close();

    return new ResponseEntity<byte[]>(baos.toByteArray(), headers, HttpStatus.OK);
   }

The image is being rendered in the browser like:

   <img id="userSignature" width="296" height="110" style="border:0px" src="/webapp/service/submissions/signature/user/${subid}" alt="User signature" />

I have not changed this class and I am told that it did work, I am able to create images from both byte arrays and they are ok and looks the same and I able to render the signature string ok for testing like:

  <IMG SRC="data:image/png;base64, <base_64_string>" ALT=""> 

has anyone experienced similar issues or know what could be causing this?

I have now tried sending an image from my file system already created as png and that also fails.

I have now noticed that CSV files do not download properly in the app and they stream in the same way:

       @RequestMapping(value = "/results/csv", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<byte[]> getResultsInCsvFormat() throws IOException {
like image 949
berimbolo Avatar asked Sep 20 '25 09:09

berimbolo


1 Answers

I have successfully returned file contents with the help of an InputStream:

@RequestMapping(value = "/submissions/signature/{type}/{id}", 
                method = RequestMethod.GET)
public HttpEntity getFile(HttpServletResponse response,
                          @PathVariable String type, 
                          @PathVariable Integer id) {
    String base64 = "foo"; // get base-64 encoded string from db
    byte[] bytes = Base64.decodeBase64(base64);
    try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
        StreamUtils.copy(inputStream, response.getOutputStream());
        response.setContentType(MediaType.IMAGE_PNG_VALUE);
    } catch (IOException e) {
        // handle
    }
    return new ResponseEntity(HttpStatus.OK);
}

Note that I'm not using ResponseBody, and in my working version I am using MediaType.APPLICATION_OCTET_STREAM_VALUE rather than the actual file content type.

like image 186
beerbajay Avatar answered Sep 22 '25 19:09

beerbajay