zoukankan      html  css  js  c++  java
  • 编解码(编码解码)常识

    字符编码

    字符编码就是以二进制的数字来对应字符集的字符,常见字符编码方式有:ISO-8859-1(不支持中文),GB2312,GBK,UTF-8等.在JavaWeb中, 经常遇到的需要编码/解码的场景有响应编码/请求编码/URL编码:

    响应编码

    服务器发送数据给客户端由Response对象完成,如果响应数据是二进制流,就无需考虑编码问题.如果响应数据为字符流,那么就一定要考虑编码问题:

    response.getWriter()默认使用ISO-889-1发送数据,而该字符集不支持中文,因此遇到中文就一定会乱码.

    在需要发送中文时, 需要使用:

    response.setCharacterEncoding("UTF-8");

    // getWriter() ...

    设置编码方式,由于在getWriter()输出前已经设置了UTF-8编码,因此输出字符均为UTF-8编码,但我们并未告诉客户端使用什么编码来读取响应数据,因此我们需要在响应头中设置编码信息(使用Content-Type):

    response.setContentType("text/html;charset=UTF-8");

    // getWriter() ...

    注意: 这句代码不只在响应头中添加了编码信息,还相当于调用了一次response.setCharacterEncoding("UTF-8");

    请求编码

    1. 浏览器地址栏编码

    在浏览器地址栏书写字符数据,由浏览器编码后发送给服务器,因此如果在地址栏输入中文,则其编码方式由浏览器决定:

    浏览器编码
    IE/FireFox GB2312
    Chrome UTF-8

    2. 页面请求

    如果通过页面的超链接/表单向服务器发送数据,那么其编码方式由当前页面的编码方式确定:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    3. GET

    当客户端发送GET请求时,无论客户端发送的数据编码方式为何,服务端均以ISO-8859-1解码(Tomcat8.x之后改用UTF-8),这就需要我们在request.getParameter()获取数据后再转换成正确的编码:

    private Map<String, String> convertToParameterMap(HttpServletRequest request) throws UnsupportedEncodingException {

        Enumeration<String> names = request.getParameterNames();

        Map<String, String> parameters = new HashMap<String, String>();

        if (names != null) {

            while (names.hasMoreElements()) {

                String name = names.nextElement();

                String value = request.getParameter(name);

                parameters.put(name, new String(value.getBytes("ISO-8859-1"), "UTF-8"));

            }

        }

        return parameters;

    }

    4. POST

    当客户端发送POST请求时,服务端也是默认使用iOS-8859-1解码,但POST的数据是通过请求体传送过来,因此POST请求可以通过request.setCharacterEncoding()来指定请求体编码方式:

    private Map<String, String> convertToParameterMap(HttpServletRequest request) throws IOException {

        Map<String, String> parameters = new HashMap<String, String>();

        if (request.getMethod().equals("POST")) {

            request.setCharacterEncoding("UTF-8");

            Enumeration<String> names = request.getParameterNames();

            while (names.hasMoreElements()) {

                String key = names.nextElement();

                parameters.put(key, request.getParameter(key));

            }

        } else {

            Enumeration<String> names = request.getParameterNames();

            while (names.hasMoreElements()) {

                String key = names.nextElement();

                String value = request.getParameter(key);

                parameters.put(key, new String(value.getBytes("ISO-8859-1"), "UTF-8"));

            }

        }

        return parameters;

    }

    URL编码

    网络标准RFC 1738规定:

    “…Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”

    “只有字母和数字[0-9a-zA-Z]、一些特殊符号"$-_.+!*'(),"[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”

    如果URL中有汉字,就必须编码后使用, 而URL编码过程其实很简单:

    首先需要指定一种字符编码,把字符串解码后得到byte[],然后把小于0的字节+256,再将其转换成16进制,最后前面再添加一个%.

    这个编码过程在Java中已经封装成了现成的库, 可直接使用:

    URLEncoder描述
    static String encode(String s, String enc) Translates a string into application/x-www-form-urlencoded format using a specific encoding scheme.
    URLDecoder描述
    static String decode(String s, String enc) Decodes a application/x-www-form-urlencoded string using a specific encoding scheme.

    注: 在Web中Tomcat容器会自动识别URL是否已经编码并自动解码.

  • 相关阅读:
    dom4j 创建XML文件
    Convert.ToInt32()与int.Parse()的区别
    委托
    工厂模式
    策略模式
    大型网站架构演化
    字符串反转(面试)
    switch(面试)
    带宽计算
    新语法
  • 原文地址:https://www.cnblogs.com/gossip/p/5725193.html
Copyright © 2011-2022 走看看