http请求编解码、JSP页面乱码问题梳理

以下内容是基于java开发来作说明的...........

如果你只是想解决问题,请你按照以下两点加上配置即可:

第一:在web.xml文件中添加spring提供的通用的请求解码,响应编码字符集

<filter>
        <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

这个配置可以解决http请求中放于请求体中的参数的解码与编码,所以可以直接解决客户端发送的post请求的乱码以及服务端返回数据的编码问题

第二,分为两种情况:

1.JSP页面乱码,加上<%@ page language="java" contentType="text/html; charset=UTF-8"  %>

2.get请求,后端接收到的字符乱码,如果你用的是tomcat服务器,在conf/server.xml中配置如下两点中的一点就可以:

<Connector>中 添加uriEncoding="UTF-8"   

<Connector>中 添加useBodyEncodingForURI="true"  

或者在代码中添加String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

如果你想了解发送请求->接受请求->返回响应->渲染页面这个过程消息内容到底是如何编码解码的你就接着往下看

网上查了不少关于http请求编码解码的文章,看完感觉都没完全理清楚,没办法只能自己验证:

我们首先说下http消息头中content-type属性:Content-Type:text/html;charset=UTF-8,注意下面我们只针对charset这个属性来做说明:
无论是请求还是响应,这都代表了一种编码解码字符集协商,客户端与服务端告诉对方我是用的这个字符集对消息体进行编码的(注意这里是消息体),你也用这个来解码吧,于是接受的一方就会通过协商的这个字符集进行解码(我们下面说到的字符集协商就代表消息头中的这个属性)

服务端响应客户端时指定编码方式有如下两个:
response.setContentType("text/plain; charset=utf-8")  
response.setCharacterEncoding("charset=utf-8");
两种方式都可以设置响应时,服务端对响应内容的编码方式
并且前者还会同时设置响应消息头中的content-type类型,进行字符集协商,我们上面在web.xml中添加的过滤器就是这种方式

JSP文件中的编码解码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
我们看到这里涉及到两个编码:
1.其中pageEncoding="UTF-8"这个好理解,无论什么文件自身都会有一个编码方式,而这个就指定了jsp文件本身内容的编码方式,这个与请求交互中的编解码没有关系
2.contentType="charset=UTF-8"  这个属性有三个作用:
a.针对页面本身:替代上面说的pageEncoding指定页面自身编码(所以如果指定了这个参数,pageEncoding去掉也没有关系,待会我会用我试验的截图给大家解释)
b.针对服务端返回页面响应内容:表示服务端返回我这个页面时对响应内容的编码方式,以及响应消息头中的字符集协商
c.针对客户端页面提交的请求内容:指定页面提交请求时对请求内容的编码方式(不包括ajax请求啊),以及请求消息头中的字符集协商
我们都知道,jsp文件都会被编译为servlet的class文件来执行,我们看到的浏览器页面内容(静态的以及动态的)都是在servlet中生成并输出到浏览器页面的,在Tomcat中生成的java及class文件在tomcat\work目录下,我用我本地的一个jsp做了如下试验:

当我修改JSP文件的charset=iso-8859-1后,  

tomcat对应生成的java文件如下: 

 

图片上我标了两个重点:

 

    第一个是servlet设置了响应时的字符集协商,代表了servlet会用这个字符集对接下来要输出给页面的内容进行编码,并且告诉客户端你就用我这个字符集对内容进行解码。这个验证了上面说的jsp页面指定的b作用,

    第二个是jsp里自带的中文字被编码成这个样子,这验证了我上面说的charset可以替代pageEncoding来指定页面自身的编码。

当我改成charset=utf-8后,上面标的两点都对应改动了。

上面说了服务端对客户端的响应编解码,下面我们再看客户端请求服务端,分为以下几种情况:

1.页面的get请求(包含浏览器地址栏输入url直接请求)
2.页面form表单的 post请求
3.ajax的get post请求
我们分别说明上述几种情况客户端是如何对请求内容进行编码,服务端又是如何对请求内容进行解码的
首先:对于前两种情况,客户端都会按照页面中设置的contentType中指定的字符集对请求内容进行编码,并且会设置请求消息头中的content-type类型,上面说了,这就相当于告诉服务端你就用这个来对我的消息中的消息体进行解码就好了
对于post请求由于请求参数都在消息体中,所以服务端解码得出的参数肯定不会乱码
而对于get请求,请求参数都在Url中,而服务端对url和消息体解码的方式是不一致的,
所以服务端需要指定对Url的解码方式以防止用默认方式解码,tomcat服务器中指定Url解码方式的配置有如下两种:
1)在server.xml的<Connector>中 添加uriEncoding="UTF-8"   这个很好理解
2)在server.xml的<Connector>中 添加useBodyEncodingForURI="true"  这个意思就是服务端收到的http请求头中指定的消息体编码方式是什么,就用这个编码来对uri进行解码
其次:对于ajax请求,编码方式与页面指定的charset就无关了,需要另行指定,使用jquery来发送ajax请求时,jquery已经指定了编码的方式为UTF-8,并且设置了消息体编码协商。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值