2012-01-06 53 views
4

我已經編寫了一個下載Servlet以基於messageID參數返回文件。以下是doGet方法。通過HTTP下載文件在java中獲取

@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(); 
} 

然後我寫了一些代碼來檢索文件。

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(); 
    } 

此代碼正常工作。我可以下載音頻文件並且它可以正常工作。我想知道的是如何在可能的情況下獲取下載文件的名稱,而不是將其命名爲我自己的名稱。另外,是否可以在不需要從流中讀取文件的情況下獲取文件(也許有些庫可以爲您做)?我有點想隱藏骯髒的東西。

謝謝

+0

您可以使用Content-disposition條目指定所需的任何文件名。 – adatapost 2012-01-06 05:05:59

+0

查看IOUtils的commons-io以幫助使用流。 – Steven 2012-01-06 05:10:08

+0

如何從客戶端應用程序獲取該信息?我必須解析標題嗎? – 2012-01-06 05:10:55

回答

0

有附件,文件將正確提供與提供的名稱。在內聯時,瀏覽器似乎忽略了文件名,並且通常在保存內聯內容時將URL的servletname部分作爲默認名稱。

您可以嘗試將該URL映射到適當的文件名(如果適用)。

這裏有一個SO相關的問題:Securly download file inside browser with correct filename

您也可能會發現此鏈接有用:Filename attribute for Inline Content-Disposition Meaningless?

我認爲你不能下載文件,而無需流。對於I/O你必須使用流。

+0

感謝您的回答,但我無法映射到文件名式URL,因爲這些文件取決於客戶端知道的唯一ID。我可以這樣做,以便文件包含他們的ID在他們的名字,但我不能保證它總是imo。至於I/O,如果是這樣的話,那麼太糟糕了。 – 2012-01-06 06:40:42

1

有關設置下載文件名不響應對象下面的servlet代碼

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

編輯: 我看你已經在做了。只要嘗試刪除已添加的斜線。

+0

向下選民,請解釋原因。 – Santosh 2017-02-03 09:08:23