Servlet send the server image and save in the client


I'm new and just developing on J2EE. I am modifying an existing application (an OpenSource project). I need to save an image on a client sent by the server, but I do not know how. This activity must be done in a transparent manner without affecting the existing operation of the application.

From the tests done I get this error: java.lang.IllegalStateException: getWriter () has Already Been Called for this response.

How should carry out this task, according to your own opinion? How do I save on the client, locally, the image?


Thanks for the answers. My problem is that:

  1. the image is generated on the server, but not for direct client request (there is no link to click on web page), the picture is composed using other services on the Internet.
  2. reconstruct the image on the server.
  3. This image must be sent to the client to be saved locally.
  4. so I'd like it to appear a window where you assign the destination image
  5. plus I'd like the rest of the application were not affected by this activity.
  6. The application is yet on production.

Thank you very much for your response.

From the tests done I get this error: java.lang.IllegalStateException: getWriter () has Already Been Called for this response.

In other words, you were trying to mix the binary data of the image with the character data of the HTML output, or you were trying to do this in a JSP instead of a Servlet. This is indeed not going to work. You need to send either the image or the HTML page exclusively in response to fully separate requests.

In your JSP/HTML page just have a link to the image, like so:

<a href="imageservlet/filename.gif">click to download image</a>

Then, in a servlet listening on an url-pattern of /imageservlet/*, you just get the image as InputStream from some datasource (e.g. from local disk file system as FileInputStream) and then write it to the OutputStream of the response the usual Java IO way.

You only need to set at least the Content-Disposition response header to attachment to make sure that the client get a Save As popup dialogue, else it will be displayed straight in the browser. Setting the Content-Type and Content-Length are also important so that the browser knows what the server is sending and can predict how long the download may take.

response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");

You can find complete basic servlet example in this article.

Note: you cannot control where the client would save the image, this would be a security hole. This way websites would be able to write malicious files on client's disk unaskingly.

Update: as per your update, there are two options:

  1. You need to let the client itself fire two HTTP requests (I've answered this in your subsequent question)

  2. Create a client side application which does all the task directly at the client side and then embed this in your webpage, for example a Java Applet. With an applet you have full control over the client environment. You can execute almost all Java code you'd like to execute and you can write files to disk directly without asking client for the location to save. You only need to sign the applet by a 3rd party company or the client needs to confirm a security warning before running.