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.