响应头传递中文手动编码(url编码、base64编码)

  • 响应头:Content-Disposition
  • 格式:Content-Disposition: attachment; filename=aaa.zip
  • 作用:通知浏览器要以附件下载形式获取数据
  • 要求:动态向浏览输出一张图片,但是不要直接显示,而是以附件下载
  • 设置响应头,通知浏览器以附件下载获取数据
  1. response.setHeader("Content-Disposition","attachment; filename=3.jpg");//文件名字为非中文没有任何问题
  2. response.setHeader("Content-Disposition","attachment; filename=汽车.jpg");//如果是中文就会有问题 (响应头传递中文默认不会进行url编码,所以无法传递中文,需要手动进行url编码(请求体和请求行,响应体这些都传递中文数据会自动进行url编码
  • 手动url编码不同的浏览器不一样
  1. ie浏览器进行url编码
  2. 其他浏览器进行base64编码
  • 固定代码段(可直接拷贝) 
     String fileName="汽车.jpg";
        String ua = request.getHeader("User-Agent");
        boolean IE_LT11 = ua.contains("MSIE"); // IE11以下版本
        boolean IE11 = ua.contains("rv:11.0) like Gecko"); // IE11
        boolean Edge = ua.contains("Edge"); // win10自带的Edge浏览器
        // 如果是微软的浏览器,直接进行UTF-8编码
        if (IE_LT11 || IE11 || Edge) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            // java的编码方式和浏览器有略微的不同:对于空格,java编码后的结果是加号,
            // 而浏览器的编码结果是%20,因此将+替换成%20, 这样浏览器才能正确解析空格
            fileName = fileName.replace("+", "%20");
        }
        // 标准浏览器使用Base64编码
        else {
            Base64.Encoder encoder = Base64.getEncoder();
            fileName = encoder.encodeToString(fileName.getBytes("utf-8"));
            // =?utf-8?B?文件名?= 是告诉浏览器以Base64进行解码
            fileName = "=?utf-8?B?" + fileName + "?=";
        }
		 response.setHeader("Content-Disposition","attachment; filename="+fileName);
  • 案例: 
@WebServlet(name = "ContentDispositionServlet", urlPatterns = "/ContentDispositionServlet")
public class ContentDispositionServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

        /*
        * 响应头:Content-Disposition
        * 格式:Content-Disposition: attachment; filename=aaa.zip
        * 作用:通知浏览器要以附件下载形式获取数据
        * */

        //要求:动态向浏览输出一张图片,但是不要直接显示,而是以附件下载
        //设置响应头,通知浏览器以附件下载获取数据
        //response.setHeader("Content-Disposition","attachment; filename=3.jpg");//文件名字为非中文没有任何问题
        //response.setHeader("Content-Disposition","attachment; filename=汽车.jpg");//如果是中文就会有问题
        //响应头传递中文默认不会进行url编码,所以无法传递中文,需要手动进行url编码(请求体和请求行,响应体这些都传递中文数据会自动进行url编码)
        //手动url编码不同的浏览器不一样
        //      1.ie浏览器进行url编码
        //     2.其他浏览器进行base64编码
        String fileName="汽车.jpg";
        String ua = request.getHeader("User-Agent");
        boolean IE_LT11 = ua.contains("MSIE"); // IE11以下版本
        boolean IE11 = ua.contains("rv:11.0) like Gecko"); // IE11
        boolean Edge = ua.contains("Edge"); // win10自带的Edge浏览器
        // 如果是微软的浏览器,直接进行UTF-8编码
        if (IE_LT11 || IE11 || Edge) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            // java的编码方式和浏览器有略微的不同:对于空格,java编码后的结果是加号,
            // 而浏览器的编码结果是%20,因此将+替换成%20, 这样浏览器才能正确解析空格
            fileName = fileName.replace("+", "%20");
        }
        // 标准浏览器使用Base64编码
        else {
            Base64.Encoder encoder = Base64.getEncoder();
            fileName = encoder.encodeToString(fileName.getBytes("utf-8"));
            // =?utf-8?B?文件名?= 是告诉浏览器以Base64进行解码
            fileName = "=?utf-8?B?" + fileName + "?=";
        }
		
        response.setHeader("Content-Disposition","attachment; filename="+fileName);

        String realPath = getServletContext().getRealPath("img/3.jpg");
        System.out.println("realPath="+realPath);
        InputStream inputStream = new FileInputStream(realPath);
        byte[] bytes = new byte[1024];
        int length=-1;
        while((length=inputStream.read(bytes))!=-1){
            //将读取到的内容输出到浏览器
            response.getOutputStream().write(bytes,0,length);
        }
        //关闭流
        inputStream.close();
    }
}

猜你喜欢

转载自blog.csdn.net/Huangyuhua068/article/details/82632954