• Spring MVC 使用介绍(十)—— 编码


    一、概述

    客户端与服务器端在交互过程中,需要将字符以某种编码方式转化为字节流进行传输,因此涉及字符的编码和解码。某一方以编码方案A编码,另一方须以同样的编码方案解码,否则会出现乱码。

    客户端与服务器端的交互可分为三种:

    • 服务端向客户端传递数据
    • 客户端向服务端传递数据(POST)
    • 客户端向服务端传递数据(GET)

    服务端在不指定编码方式时,默认使用 ISO-8859-1 解码

    客户端在使用 encodeURIComponent() 方法时,使用 UTF-8 编码

    二、服务端向客户端传递数据

    服务端向客户端传递数据依赖HttpServletResponse类提供的方法,需要两步:

    1、以某种编码写数据

    response.getOutputStream().write("异常处理hello".getBytes("UTF-8"));

    或者

    response.setCharacterEncoding("UTF-8");
    response.getWriter().write("异常处理hello");

    2、添加响应头,告知客户端解码方式

    response.addHeader("content-type", "text/html;charset=UTF-8");

    三、客户端向服务端传递数据(POST)

    客户端向服务端传递数据依赖HttpServletRequest类提供的方法,需要两步:

    1、设置解码方式

    request.setCharacterEncoding("UTF-8");

    2、读取参数

    String name = request.getParameter("name");
    Integer age = Integer.valueOf(request.getParameter("age"));

    测试请求包(使用Fiddler发起)

    POST http://localhost:8080/java-web-test/encoding/1 HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    name=%E9%80%89%E6%8B%A9%E5%A4%A7%E4%BA%8E%E5%8A%AA%E5%8A%9B&age=859

    四、客户端向服务端传递数据(GET)

    客户端通过GET方式(即通过url)传递参数,须以如下方式解析:

    String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

    测试:http://localhost:8080/java-web-test/encoding/1?name=%E9%80%89%E6%8B%A9&age=52

    即服务端默认以 ISO-8859-1 编码方式解析,解析时须以 ISO-8859-1 编码方式还原为字节码,再在以 UTF-8 编码方式解码

    补充:

    浏览器的encodeURIComponent()编码方式是将特定字符以 UTF-8 方式编码为二进制,再以%为分隔、以十六进制方式展示,如:

    encodeURIComponent('选择'); // 输出:%E9%80%89%E6%8B%A9

    java等价代码:

    String str = URLEncoder.encode("选择", "UTF-8");

    同样,decodeURIComponent() 解码方式是将以%为分隔的十六进制字符转换为二进制,再以 UTF-8 方式解码

    decodeURIComponent("%E9%80%89%E6%8B%A9") // 输出:选择

    java等价代码:

    String str = URLDecoder.decode("%E9%80%89%E6%8B%A9", "UTF-8");

    五、web.xml中设置编码方式

    web.xml中,编码方式的设置可通过添加过滤器实现:

     <filter>
         <filter-name>encodingFilter</filter-name>
         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
         <init-param>
             <param-name>encoding</param-name>
             <param-value>UTF-8</param-value>
         </init-param>
         <init-param>
             <param-name>forceEncoding</param-name>
             <param-value>true</param-value>
       </init-param>
     </filter>
     <filter-mapping>
         <filter-name>encodingFilter</filter-name>
         <url-pattern>/*</url-pattern>
     </filter-mapping>

    过滤器的部分源码如下:

        @Override
        protected void doFilterInternal(
                HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
    
            if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
                request.setCharacterEncoding(this.encoding);
                if (this.forceEncoding) {
                    response.setCharacterEncoding(this.encoding);
                }
            }
            filterChain.doFilter(request, response);
        }

    即设置了请求与响应内容区的编码方式,但对GET请求无处理,因此仍然需要另外处理,如下:

    @RestController
    public class TestController {
        
        @RequestMapping(value = "/hello")
        public Map<String, Object> helloWorld(@RequestParam("name") String name) throws UnsupportedEncodingException {
    
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("name", new String(name.getBytes("ISO-8859-1"), "UTF-8"));
            return map;
        }
    }

    测试:http://localhost:8080/myweb/hello?name=%E7%A8%8B%E5%90%9B&age=29

    例外一种解决方法为添加过滤器,详细可参考javaweb学习总结(四十三)——Filter高级开发

    参考:

    javaweb学习总结(七)——HttpServletResponse对象(一)

    javaweb学习总结(十)——HttpServletRequest对象(一)

    javaweb学习总结(四十三)——Filter高级开发

  • 相关阅读:
    Java的接口及实例
    卷积函数的参数为Conv2d(in_channels, out_channels, kernel_size, stride, padding, ...),一般关心这5个参数即可
    torch.randn和torch.rand的区别
    Pytorch 里 nn.AdaptiveAvgPool2d(output_size) 原理是什么?
    Python中*args、**args到底是什么、有啥区别、怎么用
    padding输入值是tuple数组,其含义是
    矩阵/图像边长经过卷积操作后的尺寸计算方法:
    CIFAR-10 数据集
    vgg code
    Epoch、Iteration、Batchsize
  • 原文地址:https://www.cnblogs.com/MattCheng/p/9208801.html
Copyright © 2020-2023  润新知