5

I am trying to return a ZipInputStream containing two different outputstreams as a javax.ws.rs.core.Response Stream. When I make a web service call to retrieve the stream, I notice that I get an empty stream back. I have tried returning a GZipInputStream before, and I have received the expected stream on the client side. Could there be an issue with ZipInputStream that prevents it from being returned properly? I am using javax 2.4 (servlet-api) This is how my jax-rs service looks like (I have simplified it a bit):

 @GET
 @Produces({"application/zip", MediaType.APPLICATION_XML})
 public Response getZipFiles(@PathParam("id") final Integer id){

    //Get required resources here
    ByteArrayOutputStream bundledStream = new ByteArrayOutputStream();
    ZipOutputStream out = new ZipOutputStream(bundledStream);
    out.putNextEntry(new ZipEntry("Item A"));
    out.write(outputStream.toByteArray());
    out.closeEntry();

    out.putNextEntry(new ZipEntry("Item B"));
    out.write(defectiveBillOutputStream.toByteArray());
    out.closeEntry();

    out.close();
    bundledStream.close();

    ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(bundledStream.toByteArray()));
    return Response.ok(zis).build();
 }

And this is the code that calls the service. I am using axis 1.4:

 HttpMethodBase getBillGroup = null;
 String id = "1234";
 String absoluteUrl = baseURL + BASE_SERVICE_PATH.replace("@id@",id) ;
 getZip = new GetMethod(absoluteUrl);

 HttpClient httpClient =  new HttpClient();
 try {
      httpClient.executeMethod(getZip);
 }
 catch (Exception e) {
      LOGGER.error("Error during retrieval " + e.getMessage());

 }

 InputStream dataToConvert =  getZip.getResponseBodyAsStream();
 ZipInputStream in = new ZipInputStream(dataToConvert);
 ZipEntry itemA = in.getNextEntry();
 //Do more things

On the last line, itemA should have been the first entry added to the stream in the Jax-RS Service, but I am getting a null back. Any idea what might be causing this?

theseeker
  • 168
  • 1
  • 5

1 Answers1

1

In the first block use a ByteArrayInputStream instead of a ZipInputStream, which iterates complex zip entries.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Yes! Thank you. This works. I am getting some data back (Previously, all I got was an empty stream). Do you know how I would convert the stream on the second block and iterate through the zipentries now? The code as it stands still returns null on the last line. – theseeker Jan 09 '12 at 21:16
  • Ok just did this: ZipInputStream in = new ZipInputStream(getZip.getResponseBodyAsStream()); and I get my itemA and itemB. Thanks for your help! – theseeker Jan 09 '12 at 23:28
  • `@Produces` seems better without the MediaType.APPLICATION_XML parameter (not sure). And instead of the stream, you can try passing the byte[] as entity parameter to `ok`. _I am not experienced._ You could first try downloading it as binary InputStream, i.o. ZipInputStream, to try. – Joop Eggen Jan 09 '12 at 23:35
  • XML is added, because in case of errors, we return an xml with error details. But the change in my code fragment (in my previous comment) did the trick. – theseeker Jan 12 '12 at 01:54