jsp safari浏览器windows文件下载内容配置文件名成了 -

时间:2017-06-21 06:50:57

标签: java jsp tomcat safari

下面的代码用于下载附件编码中文字符的文件名。

w_inf_src = new File(p_filepath);
   w_inf = new FileInputStream(w_inf_src);
   p_response.setContentType(w_mime+";charset=UTF-8");
   p_response.setContentLength(new Long(w_inf_src.length()).intValue());
   p_response.setCharacterEncoding("UTF-8");
   p_request.setCharacterEncoding("UTF-8");

   p_response.setHeader("Content-disposition",
             "attachment;filename=\"" + (new java.net.URI(null, null, p_request, p_filename, null)).toASCIIString() + "\"");


   // Download File In Progress  
   w_outf = p_response.getOutputStream();
   w_bof = new BufferedOutputStream(w_outf);
   while ( (w_bytes_read = w_inf.read(w_buffer, 0, w_buffer.length)) != -1)
     w_bof.write(w_buffer, 0, w_bytes_read);      
   w_bof.flush();

我也尝试过文件名* = UTF-8''<编码文件名>但是不起作用

1 个答案:

答案 0 :(得分:1)

如果您至少使用java 7和Sevlet API 3.0,则可以采用以下方法:

File w_inf_src = new File(p_filepath);
String encoding = StandardCharsets.UTF_8.name();
String w_disposition = String.format("%s;filename=\"%3$s\"; filename*=%2$s''%3$s",
    Part.ATTACHMENT,
    encoding,
    URLEncoder.encode(p_filename, encoding).replace("+", "%20"));

p_response.setContentType(w_mime);
p_response.setContentLengthLong(w_inf_src.length());
p_response.setCharacterEncoding(encoding);
p_response.setHeader("Content-Disposition", w_disposition);

byte[] w_buffer = new byte[p_response.getBufferSize()];
try(FileInputStream w_inf = new FileInputStream(w_inf_src);
    OutputStream w_outf = p_response.getOutputStream())
{
    int n;
    while((n = w_inf.read(w_buffer)) != -1)
    {
        w_outf.write(w_buffer, 0, n);
    }
}

一些注意事项:

  1. 这是您将获得的最准确的处置表单,因为它是 urlencoded 空间清理
  2. content-type content-encoding
  3. 中设置编码是多余的
  4. 设置请求编码是多余的:你不是在阅读。
  5. 使用BufferedInputStream是多余的,因为响应具有内部缓冲
  6. 使用您自己的最大可用大小缓冲区(respose.getBufferSize()
  7. 尽可能使用try-with-resources(如果您使用的是Java 7 +)
  8. 如果您使用的是Servlet API 3.0+ response.setContentLengthLong(),他们终于明白整数是不够的
  9. 或者使用:response.setHeader("Content-Length", String.valueOf(w_inf_src.length()));:这可以确保不会将大长度切割为int size