Java's Response File Download Case

Download Requirements:

1. The page displays a hyperlink 
2. Click on the hyperlink to download the pop-up message box 
3. Complete the picture file download

Analysis process:

1. If a hyperlink to a resource that can be parsed by the browser, the browser display, if not resolved, then download the message box pops up. Does not meet the requirements 
2. Any resources must download prompt pop-up box 
3. Use the response header resource Open: 
   Content-Disposition: Attachment; filename = xxx

step:

1. Define page, edit hyperlink href attribute pointing Servlet, passing the name of the resource filename 
2 defines the Servlet 
	1. Get the name of the file 
	2. file input stream of bytes loaded into memory 
	3 in response to the specified response header: content-disposition: Attachment; filename XXX = 
	4. the response written into the output data stream

  

Code:

  Download page:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>文件下载</title>
 6 </head>
 7 <body>
 8 
 9 
10     <a href="/day13/img/狐狸.jpg">图片1</a>
11 
12     <a href= "/ Day13 / IMG / 2.jpg" > Image 2 </ A > 
13 is  
14      < A the href = "/ Day13 / IMG / 1.avi" > Video </ A > 
15      < HR > 
16  
. 17  
18 is      < A the href = "/ day13 / downloadservlet? filename = fox .jpg" > image. 1 </ A > 
. 19  
20 is      < A the href = "/ day13 / downloadservlet? filename = 2.jpg" > image 2 </ A > 
21 is  
22 is      <a href="/day13/downloadservlet?filename=1.avi">视频</a>
23 
24 
25 
26 
27 </body>
28 </html>

 

  DownLoadServlet class

 1 import javax.servlet.ServletContext;
 2 import javax.servlet.ServletException;
 3 import javax.servlet.ServletOutputStream;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.FileInputStream;
 9 import java.io.IOException;
10 
11 @WebServlet("/downloadservlet")
12 public class downloadservlet extends HttpServlet {
13     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         //1获取请求参数,文件名称
15         String filename = request.getParameter("filename");
16 
17         //2使用字节输入流加载文件进内存
18         // 2.1 找文件服务器路径
19         ServletContext servletContext = this.getServletContext();
20         String realPath = servletContext.getRealPath("/img/" + filename);
21 
22         //2.2 使用字节流关联
23         FileInputStream fis = new FileInputStream(realPath);
24 
25         //3 设置 response 的响应头
26         // 3.1 设置响应头类型:content-type
27         String mimeType = servletContext.getMimeType(filename);
28         response.setHeader("content-type",mimeType);
29         // 3.2 设置响应头打开方式:content-disposition
30 
31         response.setHeader("content-disposition","attachment;filename="+filename);
32 
33 
34         // 4. 将输入流的数据写出到输出流中
35         ServletOutputStream sos = response.getOutputStream();
36 
37         byte[] buff = new byte[1024*8];
38         int len = 0;
39 
40         while((len = fis.read(buff)) != -1) {
41             sos.write(buff,0,buff.length);
42         }
43 
44         // 关闭流对象
45         fis.close();
46     }
47 
48     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
49         this.doPost(request, response);
50     }
51 }

 

  上面的案例中发现,当下载的文件名字是中文的时候,下载的时候会出现乱码。

文件名中文乱码问题

  解决思路:

    (1)获取客户端使用的浏览器版本信息

    (2)根据不同的版本信息,设置 filename 的编码方式不同

  编码工具类:

  使用 Base64 编码,需要导入 commons-codec-1.13.jar 包。

 1 package cn.itcast.download;
 2 
 3 
 4 import org.apache.commons.codec.binary.Base64;   
 5 
 6 import java.io.UnsupportedEncodingException;
 7 import java.net.URLEncoder;
 8 
 9 
10 public class DownLoadUtils {
11 
12     public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {
13         if (agent.contains("MSIE")) {
14             // IE浏览器
15             filename = URLEncoder.encode(filename, "utf-8");
16             filename = filename.replace("+", " ");
17         } else if (agent.contains("Firefox")) {
18             Base64 base64Encoder = new Base64();
19             // 火狐浏览器
20             //BASE64Encoder base64Encoder = new BASE64Encoder();
21             filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
22         } else {
23             // 其它浏览器
24             filename = URLEncoder.encode(filename, "utf-8");
25         }
26         return filename;
27     }
28 }

 

  DownLoadServlet 类(改进):

 1 package cn.itcast.download;
 2 
 3 import javax.servlet.ServletContext;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.ServletOutputStream;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import java.io.FileInputStream;
11 import java.io.IOException;
12 
13 @WebServlet("/downloadservlet")
14 public class downloadservlet extends HttpServlet {
15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
16         //1获取请求参数,文件名称
17         String filename = request.getParameter("filename");
18 
19         //2使用字节输入流加载文件进内存
20         // 2.1 找文件服务器路径
21         ServletContext servletContext = this.getServletContext();
22         String realPath = servletContext.getRealPath("/img/" + filename);
23 
24         //2.2 使用字节流关联
25         FileInputStream fis = new FileInputStream(realPath);
26 
27         //3 设置 response 的响应头
28         // 3.1 设置响应头类型:content-type
29         String mimeType = servletContext.getMimeType(filename);
30         response.setHeader("content-type",mimeType);
31         // 3.2 设置响应头打开方式:content-disposition
32 
33         // 3.3 解决中文文件名问题
34           // 1 获取 user-agent 请求头
35         String agent = request.getHeader("user-agent");
36         // 2 使用工具类方法编码文件即可
37         filename = DownLoadUtils.getFileName(agent, filename);
38 
39         response.setHeader("content-disposition","attachment;filename="+filename);
40 
41 
42         // 4. 将输入流的数据写出到输出流中
43         ServletOutputStream sos = response.getOutputStream();
44 
45         byte[] buff = new byte[1024*8];
46         int len = 0;
47 
48         while((len = fis.read(buff)) != -1) {
49             sos.write(buff,0,buff.length);
50         }
51 
52         // 关闭流对象
53         fis.close();
54     }
55 
56     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
57         this.doPost(request, response);
58     }
59 }

 

Guess you like

Origin www.cnblogs.com/niujifei/p/11621866.html