2

I have written following server code :
Note for lack of time I removed annotations on method but I correctly set them
@Produces({ "application/xml", "application/zip", "application/octet-stream" })

public Response getFile(@PathParam("fileName") String fileName) {
    final File file = new File(FILE_STORE_PATH + fileName);
    final String filePath = FILE_STORE_PATH + fileName;
    final boolean isZip = filePath.endsWith(".zip");
    System.out.println("[Received Request for download of file " + file.getAbsolutePath() + "]");
    if (isZip) {
        try {
            System.out.println("[Dispatching a zip file]");
            ResponseBuilder response =
                    Response.ok(new FileInputStream(file), MediaType.APPLICATION_OCTET_STREAM_TYPE);
            response.header("content-disposition", "inline;filename=" + fileName);
            return response.build();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
    return getNIOResponse(filePath, file);
}

/**
 * 
 * @param filePath
 * @return
 */
private Response getNIOResponse(final String filePath, final File file) {
    StreamingOutput fileStream = new StreamingOutput() {
        @Override
        public void write(java.io.OutputStream output) throws IOException, WebApplicationException {
            try {
                System.out.println("[Dispatching a xml file]");
                java.nio.file.Path path = Paths.get(filePath);
                byte[] data = Files.readAllBytes(path);
                output.write(data);
                output.flush();
            } catch (Exception e) {
                //LOG.error("STET File not found in path : " + filePath);
                throw new WebApplicationException("File Not Found : " + filePath);
            }
        }
    };
    ResponseBuilder response = Response.ok(fileStream);
    response.header("Content-Disposition", "attachment; filename=" + file.getName());
    return response.build();

}

Now on client side I have following code :

            ClientConfig clientConfig = new ClientConfig();
            clientConfig.register(MultiPartFeature.class);
            if (isLoggingEnabled(externalParams)) {
                clientConfig.register(
                        new LoggingFeature(null, getLogLevel(externalParams), Verbosity.PAYLOAD_ANY, null));
            }
            ...
            ...
            Invocation.Builder builder = target.request();
            if (mime != null && mime.length > 0) {
                builder.accept(mime);
            }//mime is an array mime[] = new String[]{"application/xml","application/zip"}
            Response response = builder.get();
            FileServerResponseDTO dto = new FileServerResponseDTO();
            dto.setResponseStatus(Response.Status.fromStatusCode(response.getStatus()));
            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                InputStream is = response.readEntity(InputStream.class);
                dto.setResult(is);
            }

Now the problem is I my server can expect either a zip file download request or a xml file (although I needn't make a different way of handling resource types at server side) but I am trying lots of ways to fix my problem, so for Zip I send the FileInputStream with response and unfortunately my client code cannot read ZipInputStream so if I do this

InputStream stream = response.readEntity(InputStream.class);
ZipInputStream zipstream = new ZipInputStream(stream);
    try {
        return zipstream.getNextEntry() != null;
    } catch (IOException ioe) {
        LOGGER.error("Error while processing this zip input stream: " + ioe);
    }

it returns me false plus also even with xml file download request (not zip one) I am receiving strange error at client side when I try to create XMLStreamReader out of it Caused by: java.lang.RuntimeException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'U' (code 85) in prolog; expected '<' at javax.xml.stream.SerializableLocation@de6451a3

Could anyone please help me what I am doing wrong here. Idea is to process a zip file as a zip and read the contents and process them and same for xml file if received.
Note : I am using Jersey 2.1 and also my sevrer is Embedded Jetty and Client code is running on IBM Websphere.

Update : When I hit the url on browser I get those zip as well as xml file returned correctly not damaged or anything. Only in code my jersey client cannot identify zipstream.

  • Where in your code do you ever check what the `Accept` header is. If you have a method that produces those types, then you need to check in your method for what the client is expecting, and then send the data in _that_ format. You are only sending the data in `application/octet-stream`. If the client set's the accept header as `application/xml`, then you need to send the data back in that format. Based on the `Content-Type` header on the response, the client will determine what it can do with the data. This is how content-negotiation works. Maybe do a little research on it. – Paul Samsotha Jul 12 '18 at 01:48
  • This might not be the cause of your problem, but it is good to understand this concept. – Paul Samsotha Jul 12 '18 at 01:49
  • Another aside, why are you reading the entire file into memory. You should just stream it directly to the OutputStream. Otherwise what is the purpose of using the `StreamingOutput` at all? You defeated the whole purpose. – Paul Samsotha Jul 12 '18 at 01:53
  • Server side supports 3 mime types however client is dynamic it can request either a zip file or a xml file, so I don't understand what is needed at client side. Even client is not aware what type of content its going to receive all it care is about the inputstream and determine if its a zip or a xml stream. – java_for_life Jul 12 '18 at 05:22

0 Answers0