Weird EOF Exception while trying to download file from GWT application - gwt

I am trying to download a file from GWT client. At server side there is a servlet which generates content of file as per request and send it back to the client.
Test Scenarios:
Scenario 1 If I hit url of servlet directly, it always give me desired result without any problems.
Scenario 2
Using GWT client on IE8,I am able to download file without any code changes. However on some other computer as soon as I try to write file content on response output stream, I get EOF exception.
org.mortbay.jetty.EofException
at org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:760)
at org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.java:566)
at org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:911)
at java.io.BufferedOutputStream.flush(Unknown Source)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet(ServiceDataExporterServlet.java:110)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)Creating input stream....
Code of servlet is as follows:
try
{
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
int bytesWritten=0;
while ((length = data.read(buffer)) > 0) {
bytesWritten+=length;
output.write(buffer, 0, length);
}
output.flush() // At this point I am facing EOF exception.
where data is inputStream
Via means of bytesWritten variable I have confirmed that in all the three scenarios content has been written in the same way in output stream. But not sure why it is not working in some computers.
Any points will be highly appereciated.

I do something like this to download files with GWT
In the server side:
public static void sendFileToClient(String path, String filename,
int contentLen, HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException
{
String ua = request.getHeader("User-Agent").toLowerCase();
boolean isIE = ((ua.indexOf("msie 6.0") != -1) || (ua
.indexOf("msie 7.0") != -1)) ? true : false;
String encName = URLEncoder.encode(filename, "UTF-8");
// Derived from Squirrel Mail and from
// http://www.jspwiki.org/wiki/BugSSLAndIENoCacheBug
if (request.isSecure())
{
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "-1");
response.addHeader("Cache-Control", "no-cache");
}
else
{
response.addHeader("Cache-Control", "private");
response.addHeader("Pragma", "public");
}
if (isIE)
{
response.addHeader("Content-Disposition", "attachment; filename=\"" + encName + "\"");
response.addHeader("Connection", "close");
response.setContentType("application/force-download; name=\"" + encName + "\"");
}
else
{
response.addHeader("Content-Disposition", "attachment; filename=\""
+ encName + "\"");
response.setContentType("application/octet-stream; name=\""
+ encName + "\"");
if (contentLen > 0)
response.setContentLength(contentLen);
}
try
{
FileInputStream zipIn = new FileInputStream(new File(path));
ServletOutputStream out = response.getOutputStream();
response.setBufferSize(8 * 1024);
int bufSize = response.getBufferSize();
byte[] buffer = new byte[bufSize];
BufferedInputStream bis = new BufferedInputStream(zipIn, bufSize);
int count;
while ((count = bis.read(buffer, 0, bufSize)) != -1)
{
out.write(buffer, 0, count);
}
bis.close();
zipIn.close();
out.flush();
out.close();
}
catch (FileNotFoundException e)
{
System.out.println("File not found");
}
catch (IOException e)
{
System.out.println("IO error");
}
}
I have a servlet that expects for an id and then I get the related file path and I serve it to the browser with the above code.
In the client side:
public class DownloadIFrame extends Frame implements LoadHandler,
HasLoadHandlers
{
public static final String DOWNLOAD_FRAME = "__gwt_downloadFrame";
public DownloadIFrame(String url)
{
super();
setSize("0px", "0px");
setVisible(false);
RootPanel rp = RootPanel.get(DOWNLOAD_FRAME);
if (rp != null)
{
addLoadHandler(this);
rp.add(this);
setUrl(url);
}
else
openURLInNewWindow(url);
}
native void openURLInNewWindow(String url) /*-{
$wnd.open(url);
}-*/;
public HandlerRegistration addLoadHandler(LoadHandler handler)
{
return addHandler(handler, LoadEvent.getType());
}
public void onLoad(LoadEvent event)
{
}
}
In you hosted page add this Iframe
<iframe src="javascript:''" id="__gwt_downloadFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
Then to download a file put something like this:
btnDownload.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent arg0)
{
String url = GWT.getModuleBaseURL()
+ "/downloadServlet?id=[FILE_ID]";
new DownloadIFrame(url);
}
});
I hope this helps you.
Happy coding!

It happens also if the OutputStream flushes after InputStream was closed, like this:
myInputStream.close();
myOutputStream.flush();
myOutputStream.close();
it should be like:
myOutputStream.flush();
myInputStream.close();
myOutputStream.close();
Hope it helps :-)

Related

POST multipart/form-data contents out of order

I am trying to build a web server using java sockets, everything is fine except when the browser sends POST request with file attached, when the request is received the content of the file is out of order , the file sent was txt file with line numbers when received the line numbers were out of order. is there any way I can avoid this I want ordered data (see pic 99522 is followed by 99712) THANKs
public class Server{
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
while(true) new Thread(new Client(server.accept())).start();
}
}
class Client implements Runnable {
Socket client;
OutputStream os = new FileOutputStream(new File("File12"));
InputStream in;
OutputStream out;
static ArrayList<Socket> clients = new ArrayList<Socket>();
String index;
String response;
Client(Socket client) throws IOException {
String listOfFiles = "<ol>";
this.client = client;
in = client.getInputStream();
out = client.getOutputStream();
clients.add(client);
for (File file : new File(".").listFiles()) if (file.isFile()) listOfFiles += "<li>" + file.getName() + "</li>";
listOfFiles += "</ol>";
index = "<!DOCTYPE html><html><body><h1>" + new Date() + "</h1><hr>"+listOfFiles+"<form id='upload' enctype='multipart/form-data' method='post' action='/upload'><input id='fileupload' multiple name='myfile' type='file' /><input type='submit' value='submit' id='submit' /></form></body></html>";
response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length:"+index.length()+"\r\n" +
"\r\n" +
index;
}
public void run() {
try {
String msg = "";
byte buffer[] = new byte[32*1024];
int read = in.read(buffer);
while(read != -1){
msg = new String(buffer);
System.out.println(msg);
if(msg.startsWith("POST")){
System.err.println("RAN IN POST");
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content-Type: text/plain\r\n".getBytes());
out.write(("Content-Length:"+ 4 +"\r\n").getBytes());
out.write("\r\n".getBytes());
out.write("done".getBytes());
}
if(msg.startsWith("GET")){
String path = msg.substring(msg.indexOf("/"), msg.indexOf("HTTP")).trim();
if(path.equals("/")) out.write(response.getBytes());
else {
String fileName = path.substring(1);
fileName = URLDecoder.decode(fileName,"UTF-8");
System.out.println(fileName);
File file = new File(fileName);
if(file.exists()){
System.out.println(file.getName() + " " + file.length());
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Accept-Ranges: bytes\r\n".getBytes());
out.write(("Transfer-Encoding: chunked\r\n").getBytes());
out.write("Content-Type: application/octet-stream\r\n".getBytes());
out.write(("Content-Disposition: attachment; filename=\""+file.getName()+"\"\r\n").getBytes());
out.write("\r\n".getBytes());
try{
Files.copy(Paths.get(file.getPath()) , out);
}catch(Exception e){
break;
}
}else System.out.println("file not existes");
}
}
out.flush();
os.close();
read = in.read(buffer);
}
System.err.println("closing scoket");
out.close();
in.close();
client.close();
clients.remove(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ALL right found the bug I am not clearing the buffer hence it appears again

download file using JSF 2.2 return content-length=0

I'm trying to download file from a JSF page, but when checking the content-length in the browser I find it 0.
This is my method in the managed Bean :
public void downloadFile() throws IOException {
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
File file = new File("C:\\data\\contacts.doc");
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=contacts.doc");
response.setContentLength((int) file.length());
response.setContentType("application/octet-stream");
OutputStream out = response.getOutputStream();
try {
FileInputStream input = new FileInputStream(file);
byte[] buffer =new byte[2048];
int offset = 0;
int byteRead =0;
while ((offset= input.read(buffer))!= -1 ) {
offset += byteRead ;
out.write(buffer,0,offset);
}
out.flush();
out.close();
input.close();
FacesContext.getCurrentInstance().getResponseComplete();
} catch (IOException err) {
err.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException err) {
err.printStackTrace();
}
}
this is the xhtml page :
<h:form>
<h:commandButton value="Download" action="#{helloBean.downloadFile}" />
</h:form>
I'm using Eclispe + Glassfish 4.
I was a matter of extension I put .docx instead of .doc( .doc don't exist any more)

Send a file from server to client in GWT

I am using GWT.
I have to download a file file from server to client.
Document is in the external repository.
Client sends the id of the document through a Servlet.
On server side: Using this ID document is retrieved:
Document document = (Document)session.getObject(docId);
ContentStream contentStream = document.getContentStream();
ByteArrayInputStream inputStream = (ByteArrayInputStream) contentStream.getStream();
int c;
while ((c = inputStream.read()) != -1) {
System.out.print((char) c);
}
String mime = contentStream.getMimeType();
String name = contentStream.getFileName();
InputStream strm = contentStream.getStream();
Here I can read the document.
I want to send this to the client.
How do I make this a file and send it back to the client?
In Your Servlet:
Document document =(Document)session.getObject(docId);
ContentStream contentStream = document.getContentStream();
String name = contentStream.getFileName();
response.setHeader("Content-Type", "application/octet-stream;");
response.setHeader("Content-Disposition", "attachment;filename=\"" + name + "\"");
OutputStream os = response.getOutputStream();
InputStream is =
(ByteArrayInputStream) contentStream.getStream();
BufferedInputStream buf = new BufferedInputStream(is);
int readBytes=0;
while((readBytes=buf.read())!=-1) {
os.write(readBytes);
}
os.flush();
os.close();// *important*
return;
You can create a standard servlet (which extends HttpServlet and not RemoteServiceServlet) on server side and opportunity to submit the id as servlet parameter on client side.
Now you need after getting request create the excel file and send it to the client. Browser shows automatically popup with download dialog box.
But you should make sure that you set the right content-type response headers. This header will instruct the browser which type of file is it.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileId = reguest.getParameter("fileId"); // value of file id from request
File file = CreatorExel.getFile(fileId); // your method to create file from helper class
// setting response headers
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", file.length());
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
InputStream inputStream = new FileInputStream(file);
ServletOutputStream outputStream = response.getOutputStream();
input = new BufferedInputStream(fileInput);
output = new BufferedOutputStream(outputStream);
int count;
byte[] buffer = new byte[8192]; // buffer size is 512*16
while ((count = input.read(buffer)) > 0) {
output.write(buffer, 0, count);
}
} finally {
if (output != null) {
try {
output.close();
} catch (IOException ex) {
}
}
if (input != null) {
try {
input.close();
} catch (IOException ex) {
}
}
}

FileUpload with UI in GWT. Servlet called but no file contents are retrieving

i have created fileupload widget using UI.xml. Written Servlet. My servlet is calling but no file contents are retrieving. I have pasted my code here. can you please answer what is the problem and how to retrieve the contents? This is first time using this. Please let me know .
UI
<g:FormPanel ui:field="uploadDPAFormPanel">
<g:HorizontalPanel>
<g:Label> File
Upload: </g:Label>
<g:FileUpload ui:field="fileUpload" />
<g:Button ui:field="uploadButton" title="Upload"
Upload</g:Button>
</g:HorizontalPanel>
</g:FormPanel>
Following is my imple class:
#UiHandler("uploadButton")
void onClickUploadButton(ClickEvent event) {
GWT.log("You selected: " + fileUpload.getFilename(), null);
uploadDPAFormPanel.submit();
}
public void init() {
uploadDPAFormPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
uploadDPAFormPanel.setMethod(FormPanel.METHOD_POST);
uploadDPAFormPanel.setAction(GWT.getHostPageBaseURL()
+ uploadServlet);
uploadDPAFormPanel.addSubmitHandler(new FormPanel.SubmitHandler() {
#Override
public void onSubmit(SubmitEvent event) {
if (!"".equalsIgnoreCase(fileUpload.getFilename())) {
GWT.log("UPLOADING FILE????", null);
// NOW WHAT????
}
else{
GWT.log("UPLOA event cancel");
event.cancel(); // cancel the event
}
}
});
uploadDPAFormPanel
.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
//TODO need to write code to refresh the page
doAlert("Uploaded sucessfully");
}
});
}
Following is my servlet class:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletFileUpload upload = new ServletFileUpload();
log.debug("UploadServlet upload:"+upload);
try {
FileItemIterator iter = upload.getItemIterator(request);
log.debug("UploadServlet iter:"+iter);
System.out.println("UploadServlet iter:"+iter);
while (iter.hasNext()) {
FileItemStream item = iter.next();
log.debug("UploadServlet iter:Field Name:"+item.getFieldName());
System.out.println(":Field Name:"+item.getFieldName());
System.out.println(":Name:"+item.getName());
System.out.println(":is form field:"+item.isFormField());
String name = item.getFieldName();
InputStream stream = item.openStream();
// Process the input stream
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, len);
}
int maxFileSize = 10 * (1024 * 2); // 10 megs max
if (out.size() > maxFileSize) {
throw new RuntimeException("File is > than " + maxFileSize);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
You should set a name="..." on your FileUpload.

Servlet call hanging when using S3 Java SDK

I have this servlet I call using GWT FileUpload (I don't thing it matters so much that it is GWT):
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
try {
User user = ServerUtil.validateUser(request);
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String saveFile = item.getName();
InputStream stream = item.openStream();
// Process the input stream
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, len);
}
int maxFileSize = 10 * (1024 * 1024); //10 megs max
if (out.size() > maxFileSize) {
throw new RuntimeException("File is > than " + maxFileSize);
}
// save file data
String fileName = user.getUsername() + "_" + new Date().getTime() + "_" + saveFile;
// store to S3
String imageUrl = S3PhotoUtil.storeThumbnailImage(out.toByteArray(), fileName, 100);
// return the url of the file
writer.println(imageUrl);
response.flushBuffer();
return;
}
} catch (RuntimeException e) {
writer.println(("error=" + e.getMessage()).getBytes());
} catch (FileUploadException e) {
writer.println(("error=Could not read file").getBytes());
} catch(IOException e) {
writer.println(("error=Image type not supported!").getBytes());
}
} catch (EIException e) {
e.printStackTrace();
writer.println(("error=Not logged in").getBytes());
}
}
When called the POST hangs, I check on firebug, it looks like it never gets a response. If I debug I see that all instructions are executed without any problem and the method is ran fine. The files are stored on my S3 bucket.
Now if I remove the call relating to the S3 storage it stops hanging, although obviously it doesn't do anything anymore... My conclusion is that there is something in this S3 storage that messes up with my servlet. The code itself is taken from the travel log example application # http://aws.amazon.com/code/1264287584622066
It does say needs tomcat and I'm using jetty... could that be a problem?
Thanks,
Thomas