1

I wanted to convert blob images stored in database into jpeg files and then download them as zip file.

Here is the implementation so far.

 public void downloadImages(HttpServletResponse response) throws IOException {
        List<ScreenUserEntity> users = screenUserRepository.findAll()
             .stream().filter( user -> user.getImage() != null && user.getImage().length > 0).collect(Collectors.toList());

        String filename = "Image.jpeg";
        response.setContentType("image/jpeg");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");

        byte[] decodedBytes = users.get(0).getImage();
        ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes);
        BufferedImage image = ImageIO.read(bis);

        File outputFile = new File("output.png");
        ImageIO.write(image, "png", outputFile);
    }

Is there a way to add a file/ image / zip file into the response?

Thanks for your help/

Dan
  • 559
  • 4
  • 9
  • 23
  • As spring boot does not have any special assumptions about the zip format of the file, this question is possible duplication of https://stackoverflow.com/questions/35680932/download-a-file-from-spring-boot-rest-service – Mark Bramnik Mar 10 '21 at 09:00

1 Answers1

0
List<ScreenUserEntity> users = screenUserRepository.findAll()
   .stream()
   .filter( user -> user.getImage() != null && user.getImage().length > 0)
   .collect(Collectors.toList());

This loads them all into memory. I don't think you'd want to do that; a few users and your server is just going to keel over. Best case sccenario, it kills this response handler for eating excessive memory.

Is there a way to add a file/ image / zip file into the response?

Certainly! I'm a bit confused about the usage of raw HttpServletResponse; it complicates matters very slightly here: HTTP as a standard requires that you either [A] send the size of the content you send, before you send it, or [B] use chunked transfer encoding.

If you just grab an outputstream and start sending, then by default most servlet engines in java will either store that data into memory first (that's annoying; you have way too much to send for that), or to a temp file (that's unfortunate), and don't actually send any bytes over the wire until you're completely done. You don't want that. It depends on your implementation, see also this answer. It's something you may want to investigate, e.g. using the developer tools of your favourite browser.

At any rate, once you've got that sorted, this is how you can 'stream' a zip file (make the data on-the-fly, send it across in chunks, never require a ton of memory, and nevertheless avoid making temp files):

try (OutputStream raw = response.getOutputStream();
   ZipOutputStream zip = new ZipOutputStream(raw)) {

   for (ScreenUserEntity user : screenUserRepo.findAll()) {
       byte[] img = user.getImage();
       if (img == null || img.length == 0) continue;
       zip.putNextEntry(new ZipEntry(user.getName() + ".jpg"));
       zip.write(img);
   }
}

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • Hi @rzwitserloot I appreciate your detailed explanation on the approach of implementing these functions. I have 2 blockers for these: 1) converting blob data into jpeg format, 2) compiling multiple jpeg images into a zip file so that the download will be only 1 file instead of multiple images. I applied your suggestions using 1 image and then zip it but seems the response is in strings not decoded. It was not generating the zip and jpeg file – Dan Mar 10 '21 at 13:19
  • If your image data is 'in a string', that'd bad, because strings aren't binary data. I don't know about your DB situation, but figure out how to turn data from a 'BLOB' type column from your DB outlay into a `byte[]` java-side (feel free to open a new SO question if you're having some trouble with that one). As far as 'converting' goes: Well, what's in the blob? If it's already JPG, no conversion needed. If it's PNG, then you can of course stick PNGs in the zip as well. If you want to convert PNG to JPG - separate question as well. – rzwitserloot Mar 10 '21 at 16:27