案例:文件下载
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/day15/img/1.jpg">图片1</a> <a href="/day15/img/2.jpg">图片2</a> <hr> <a href="/day15/downloadServlet?filename=1.jpg">图片1</a> <a href="/day15/downloadServlet?filename=2.jpg">图片2</a> </body> </html>
package cn.itcast.web; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; /** * @author 旗木五五开 * @create 2020-03-09 1:45 */ @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.获取请求参数,文件名称 String filename = request.getParameter("filename"); // 2.使用字节输入流进内存 // 2.1找到文件的服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/" + filename); // 2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); // 设置response的相应头 // 根据filename来获取真正的文件的mime类型 String mimeType = servletContext.getMimeType(filename); // 设置响应头类型mime:content-type response.setHeader("content-type",mimeType); // 设置响应头打开方式:content-disposition /*attachment附件 * filename对应下载提示框中的名称 * */ response.setHeader("content-disposition","attachment;filename="+filename); // 3.将输入流的数据写出到输出流中:文件对拷的操作 // 3.1文件输出流 ServletOutputStream sos = response.getOutputStream(); // 3.2定义一个字节数组,作为缓冲区 byte[] buff = new byte[1024 * 8]; // 3.3读到的个数 int len = 0; // 3.4循环读取,读到缓冲区 while ((len = (fis.read(buff))) != -1) {//不等于-1说明没有读到文件的末尾 // 3.5使用输出流,输出读出的数据 sos.write(buff,0,len);//字节流不用刷新 } // 输出流不用关,输入流要关 fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
中文名称问题
get请求Tomcat8里get请求的中文乱码问题会自动处理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/day15/img/1.jpg">图片1</a> <a href="/day15/img/2.jpg">图片2</a> <hr> <a href="/day15/downloadServlet?filename=九尾.jpg">图片1</a> <a href="/day15/downloadServlet?filename=2.jpg">图片2</a> </body> </html>
火狐
360
弹出的提示框不能正常展示中文,不同浏览器不一样
解决思路
1.获取客户端浏览器使用的版本信息
2.根据不同的版本信息,设置不同的文件名称编码
解决步骤
1.将工具类复制到当前项目
package cn.itcast.web.utils; import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownLoadUtils { public static String getFileName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }
2.获取请求头,调用工具类的方法,传入请求头,和文件名
package cn.itcast.web; import cn.itcast.web.utils.DownLoadUtils; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; /** * @author 旗木五五开 * @create 2020-03-09 1:45 */ @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.获取请求参数,文件名称 String filename = request.getParameter("filename"); // 2.使用字节输入流进内存 // 2.1找到文件的服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/" + filename); // 2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); // 设置response的相应头 // 根据filename来获取真正的文件的mime类型 String mimeType = servletContext.getMimeType(filename); // 设置响应头类型mime:content-type response.setHeader("content-type",mimeType); // 解决中文乱码---------------------------------------- // 1.获取user-agent请求头 String agent = request.getHeader("user-agent"); // 2.使用工具类方法,编码文件名称 filename = DownLoadUtils.getFileName(agent, filename); // 解决中文乱码---------------------------------------- // 设置响应头打开方式:content-disposition /*attachment附件 * filename对应下载提示框中的名称 * */ response.setHeader("content-disposition","attachment;filename="+filename); // 3.将输入流的数据写出到输出流中:文件对拷的操作 // 3.1文件输出流 ServletOutputStream sos = response.getOutputStream(); // 3.2定义一个字节数组,作为缓冲区 byte[] buff = new byte[1024 * 8]; // 3.3读到的个数 int len = 0; // 3.4循环读取,读到缓冲区 while ((len = (fis.read(buff))) != -1) {//不等于-1说明没有读到文件的末尾 // 3.5使用输出流,输出读出的数据 sos.write(buff,0,len);//字节流不用刷新 } // 输出流不用关,输入流要关 fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
今天比昨天晚,却比明天早