9

I am using a simple servlet which sends back document contents from the database as a byte array. I would like to set a content type so that it has an appropriate extension while it is being retrieved via a doGet() call.

I do have the type of the document stored as a metadata in the database (e.g. png, gif, png, xls, docx ...).

  1. What should I set as the content type so that it retains the file extension?
  2. The file gets downloaded with a name of "doc", how do I set the filename on the servlet for the data being downloaded.
user339108
  • 12,613
  • 33
  • 81
  • 112
  • possible duplicate of [make document available for download through java/servlet](http://stackoverflow.com/questions/1840703/make-document-available-for-download-through-java-servlet) – Dave Jarvis Mar 07 '11 at 05:49

2 Answers2

16

What should I set as the content type so that it retains the file extension?

Use ServletContext#getMimeType() to get the mime type based on the file name.

String mimeType = getServletContext().getMimeType(filename);

The servletcontainer usually already provides a default mime type mapping in its own web.xml. If you want to overridde or add some other, then put it as new mime mappings in webapp's web.xml. E.g.

<mime-mapping>
    <extension>docx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.wordprocessingml.document</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>xlsx</extension>
    <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
</mime-mapping>

Finally set it as the Content-Type response header:

response.setContentType(mimeType);

The file gets downloaded with a name of "doc", how do I set the filename on the servlet for the data being downloaded.

Add it to the servlet URL because some browsers like MSIE ignores the filename attribute of the content disposition.

<a href="download/filename.ext">download filename.ext</a>

If the servlet is mapped on an URL pattern of /download/*, then you can obtain it as follows

String filename = request.getPathInfo().substring(1);

Finally set it in the Content-Disposition header as well to make normal browsers happy:

response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

If you don't store filenames in DB but rather IDs or something, then use it as filename instead.

<a href="download/${file.id}.${file.ext}">download ${file.id}.${file.ext}</a>

And then in the servlet

String filename = request.getPathInfo().substring(1);
String id = filename.split("\\.")[0];
// Obtain from DB based on id.
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
8
  1. What should I set as the content type so that it retains the file extension?

You can use the setContentType method of response object to set the mime. eg:

response.setContentType("your-correct-mime-here");

2.The file gets downloaded with a name of "doc", how do I set the filename on the servlet for the data being downloaded

You can set the filename of the file being downloaded by setting the correct header. You can use Content-Disposition as shown below:

response.setHeader("Content-Disposition", "attachment; filename=\"" + your_file_name + "\"");
Abdel Raoof Olakara
  • 19,223
  • 11
  • 88
  • 133
  • see also http://stackoverflow.com/questions/1840703/make-document-available-for-download-through-java-servlet/1840925#1840925 –  Mar 07 '11 at 05:41
  • 1
    Note "your-filename" has a few problems. 1) Not a valid variable name. 2) Quotes are useful: `filename=\"" + filename + "\""`. – Dave Jarvis Mar 07 '11 at 05:50
  • @Dave, thanks for pointing out the mistakes. "your-filename" was not a variable... i was making it easy for the person to read and made a mistake by over simplified it! – Abdel Raoof Olakara Mar 07 '11 at 05:56