Jersey client downloads content partially - java

I have a Java Jersey client with which I connect to a server and download an image like this:
WebTarget webTarget = client.target(url);
Response response = webTarget.request().get();
The client response is the following:
InboundJaxrsResponse{ClientResponse{method=GET, uri=resourceURL, status=200, reason=OK}}
When I try to parse the body as an InputStream like this to a file
InputStream imageInputStream = response.readEntity(InputStream.class);
OutputStream outputStream = new FileOutputStream(new File("test.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
The input stream breaks at ~7000bytes and the content never gets parsed totally.
I have no access to the image server, and if I try to access the URL of the image in the browser, it works and the image gets downloaded.
On top the server has a self signed SSL certificate which I registered to my java keystore, can that be also part of the issue?

Related

Sending Large Image in chunks

I am sending images from my android client to java jersey restful service and I succeded in doing that.But my issue is when I try to send large images say > 1MB its consumes more time so I like to send image in CHUNKS can anyone help me in doing this.How to send(POST) image stream in CHUNKS to server
references used :
server code & client call
server function name
/*** SERVER SIDE CODE****/
#POST
#Path("/upload/{attachmentName}")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
public void uploadAttachment(
#PathParam("attachmentName") String attachmentName,
#FormParam("input") InputStream attachmentInputStream) {
InputStream content = request.getInputStream();
// do something better than this
OutputStream out = new FileOutputStream("content.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
// whatever processing you want here
out.write(buffer, 0, len);
}
out.close();
return Response.status(201).build();
}
/**********************************************/
/**
CLIENT SIDE CODE
**/
// .....
client.setChunkedEncodingSize(1024);
WebResource rootResource = client.resource("your-server-base-url");
File file = new File("your-file-path");
InputStream fileInStream = new FileInputStream(file);
String contentDisposition = "attachment; filename=\"" + file.getName() + "\"";
ClientResponse response = rootResource.path("attachment").path("upload").path("your-file-name")
.type(MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", contentDisposition)
.post(ClientResponse.class, fileInStream);
You should split the file in the client and restore part of the file in the server.
and after that you should merge the files together. Take a look at split /merge file on coderanch
Enjoy ! :)
Another path is available, if you don't want to code too much consider using :
file upload apache that is great ! :)

Downloading a file created in server using Java

I am trying to download a file from a given URL. The URL is not a direct file URL. When this URL is provided in browser manually, we get a prompt for download/save.
For example, http://www.my-domain.com/download/type/salary/format/excel
I have no issues in the URL which has the file name directly in the URL. In the above URL, based on the format and type, server generates the file.
In Java I am trying to download the file using the below code. The file is created, but the content is just the domain content and not the actual excel data.
URL url = new URL("http://www.my-domain.com/download/type/salary/format/excel");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
float totalDataRead = 0;
BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
FileOutputStream fos = new FileOutputStream("c:\\test.xls");
BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);
byte[] data = new byte[1024];
int i = 0;
while ((i = in.read(data, 0, 1024)) >= 0) {
totalDataRead = totalDataRead + i;
bout.write(data, 0, i);
}
bout.close();
in.close();
The content is whatever the server sent for that URL. You can't do anything about that from the client end. If it contained Javascript for example it won't get executed.
When you want to solve a problem you have to use the adequate tools to get the thing done. The adequate tools can be found at poi.apache.org. Have a look at Apache POI.

Getting an Image properly from My Java Web Server

I have created a simple HTTP server in Java. When the browser sends a GET request to my web server for a image file, let's say .jpg. Currently my browser does not get the image properly.
Exactly what header fields must be set?
Currently I have Date, Server, Content-type, Content-Length, Connection. I set the length by using:
fin = new FileInputStream(fileName);
contentLength = fin.available();
Content-Type is set to the correct mime-type, so no problem there.
I write the file data using:
public void sendFile (FileInputStream fin, DataOutputStream out)
{
byte[] buffer = new byte[1024];
int bytesRead;
int strCnt = 0;
try
{
int cnt = 0;
while ((bytesRead = fin.read(buffer)) != -1)
{
out.write(buffer, 0, bytesRead);
}
fin.close();
}
catch (IOException ex)
{
}
}
This is what is received by my Chrome Browser
It seems to not download the full content length.
The actual size of the image file is 2.73KB.
If no header fields are missing then what could be causing the problem?
Look likes you do not send all data. Try to add out.flush(); out.close(); before fin.close():
out.flush();
out.close();
fin.close();
I also suggest you to wrap your DataOutputStream into BufferedOutputStream. From my practice it work much more faster comparing to DataOutputStream when writing to hd/network.

Download process is not visible while servlet is downloading pdf

I m using content-disposition to download pdf . When I click the download button, the complete pdf file is downloaded first and then browser shows the dialog box to save the file. I want the browser to show the process of downloading. The following is my servlet code:
String filename = "abc.pdf";
String filepath = "/pdf/" + filename;
resp.setContentType("application/pdf");
resp.addHeader("content-disposition", "attachment; filename=" + filename);
ServletContext ctx = getServletContext();
InputStream is = ctx.getResourceAsStream(filepath);
System.out.println(is.toString());
int read = 0;
byte[] bytes = new byte[1024];
OutputStream os = resp.getOutputStream();
while ((read = is.read(bytes)) != -1) {
os.write(bytes, 0, read);
}
System.out.println(read);
os.flush();
os.close();
}catch(Exception ex){
logger.error("Exception occurred while downloading pdf -- "+ex.getMessage());
System.out.println(ex.getStackTrace());
}
The progress cannot be determined without knowing the response body's content length beforehand in the client side. To let the client know about the content length, you need to set the Content-Length header in the server side.
Change the line
InputStream is = ctx.getResourceAsStream(filepath);
to
URL resource = ctx.getResource(filepath);
URLConnection connection = resource.openConnection();
response.setContentLength(connection.getContentLength()); // <---
InputStream is = connection.getInputStream();
// ...
Unrelated to the concrete problem, your exception handling is bad. Replace the line
System.out.println(ex.getStackTrace());
by
throw new ServletException(ex);

Stream linearized PDF from servlet to browser (fast web view)

I'm running a web app that provides a servlet. this servlet opens a pdf file from a Network File System and finally streams it to the requesting browser.
All the pdf files are linearized by adobe lifecycle pdf generator and ready for fast web view.
unfortunately, the fast web view does not work. I guess it's a problem of how to open and stream the file in java code and the setting of response header info.
if i deploy a test pdf within my webapp onto the jboss AS and open it directly from the browser by url, the incrementel loading works.
can anyone help me?
Here's the code of my servlet:
response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control",
"must-revalidate, post-check=0, pre-check=0");
response.setHeader("Content-Disposition",
"inline;filename=" + documentReference);
response.setHeader("Accept-Ranges", "bytes");
File nfsPDF = new File(NFS_DIRECTORY_PATH + documentReference);
FileInputStream fis = new FileInputStream(nfsPDF);
BufferedInputStream bis = new BufferedInputStream(fis);
ServletOutputStream sos = response.getOutputStream();
byte[] buffer = new byte[(int) nfsPDF.length()];
while (true) {
int bytesRead = bis.read(buffer, 0, buffer.length);
if (bytesRead < 0) {
break;
}
sos.write(buffer, 0, bytesRead);
}
sos.flush();
//... closing...
Let's see. You want to send a file in parts, right? Then you should check Range header (HTTP Header) and send only bytes in this range. I'm correct?
I'm not familiar with "PDF fast web view" feature, but in you're code your're first reading the file completely into buffer and then you write it out. The client won't receive anything before the call to sos.flush(). In fact your while loop is obsolete because there will always be just one run.
Maybe you should try to read/write the stuff blockwise.
byte[] buffer = new byte[1024];
while (true) {
int bytesRead = bis.read(buffer, 0, buffer.length);
if (bytesRead < 0) {
break;
}
sos.write(buffer, 0, bytesRead);
sos.flush();
}
sos.flush();

Categories

Resources