5

I've written a download Servlet to return a file based on a messageID parameter. Below is the doGet method.

    @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // This messageID would be used to get the correct file eventually
    long messageID = Long.parseLong(request.getParameter("messageID"));
    String fileName = "C:\\Users\\Soto\\Desktop\\new_audio1.amr";
    File returnFile = new File(fileName);


    ServletOutputStream out = response.getOutputStream();
    ServletContext context = getServletConfig().getServletContext();
    String mimetype = context.getMimeType("C:\\Users\\Soto\\Desktop\\new_audio1.amr");

    response.setContentType((mimetype != null) ? mimetype : "application/octet-stream");
    response.setContentLength((int)returnFile.length());
    response.setHeader("Content-Disposition", "attachment; filename=\"" + "new_audio.amr" + "\"");

    FileInputStream in = new FileInputStream(returnFile);
    byte[] buffer = new byte[4096];

    int length;
    while((length = in.read(buffer)) > 0) {
        out.write(buffer, 0, length);
    }
    in.close();
    out.flush();
}

I then wrote some code to retrieve the file.

String url = "http://localhost:8080/AudioFileUpload/DownloadServlet";
    String charset = "UTF-8";

    // The id of the audio message requested
    String messageID = "1";

    //URLConnection connection = null;


    try {   
        String query = String.format("messageID=%s", URLEncoder.encode(messageID, charset));
        //URLConnection connection;
        //URL u = new URL(url + "?" + query);

        //connection = u.openConnection();
        //InputStream in = connection.getInputStream();

        HttpClient httpClient = new DefaultHttpClient();
        httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);


        HttpGet httpGet = new HttpGet(url + "?" + query);
        HttpResponse response = httpClient.execute(httpGet);

        System.out.println(response.getStatusLine());

        InputStream in = response.getEntity().getContent();

        FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\Soto\\Desktop\\new_audio2.amr"));

        byte[] buffer = new byte[4096];
        int length; 
        while((length = in.read(buffer)) > 0) {
            fos.write(buffer, 0, length);
        }
        //connection = new URL(url + "?" + query).openConnection();
        //connection.setRequestProperty("Accept-Charset", charset);

        //InputStream response = connection.getInputStream();

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Now this code works fine. I can download the audio file and it works correctly. What I want to know is how to, if possible, get the name of the file as it is downloaded instead of giving it my own name. Also, is it possible to get the file without having to read from the stream (maybe some library that does it for you)? I kind of want to hide the dirty stuff.

Thanks

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724

2 Answers2

1

For setting the download file name do the following on response object in Servlet code

 response.setHeader("Content-disposition",
                  "attachment; filename=" +
                  "new_audio1.amr" );

EDIT: I see you are already doing it. Just try removing the slashes you have added.

Santosh
  • 17,667
  • 4
  • 54
  • 79
0

With attachment, the file will be served with the provided name properly. When inline, browsers seem to ignore filename, and usually give the servletname part of the URL as default name when saving the inline contents.

You could try mapping that URL to an appropriate filename, if that is suitable.

Here's a SO related question: Securly download file inside browser with correct filename

You may also find this link useful: Filename attribute for Inline Content-Disposition Meaningless?

I think you cannot download file without streaming. For I/O you must use stream.

Community
  • 1
  • 1
Muhammad Imran Tariq
  • 22,654
  • 47
  • 125
  • 190
  • Thanks for the answer but I can't map to a filename-style URL because the files depend on the ID which is the only thing the client knows. I could make it so that the files contain their ID in their name, but I wouldn't be able to guarantee it always imo. As for I/O, if that's the case, then too bad lol. – Sotirios Delimanolis Jan 06 '12 at 06:40