彻底解决java开发web程序中的中文乱码问题

会进行几次编码

首先在浏览器传输数据的时候会进行一次编码,然后在容器(如tomcat)获取这些参数的时候会进行一次解码。

浏览器处的编码

首先,在浏览器的地址栏中输入一段如下地址:http://localhost:8080/login?name=zhangsan。这个时候由于请求地址和参数都是符合ASCII编码的,并且参数中没有一些特殊字符,如:“:”、“/”、“?”等等。所以浏览器不会对这段url进行过多的处理。

引用大佬的一段话:由于URL通过网络传递,因此,为了保证信息的兼容性和通用性,当URL包含非 ASCII字符时,必须对其进行转义。

但是如果参数中存在中文或者特殊字符的时候:http://localhost:8080/login?name=张三。在上面这段url中,参数值变成了中文,这时候把地址栏的URL复制剪贴到记事本就会发现url变成了这个样子:http://localhost:8080/login?name=%E5%BC%A0%E4%B8%89。其中%E5%BC%A0%E4%B8%89张三的UTF-8编码这就是浏览器对中文的处理。

可以用java的URLEncoder类来测试一下:

public static void main(String[] args) throws Exception {
        String text1=URLEncoder.encode("张三","UTF-8");
        System.out.println(text1);
        //输出:%E5%BC%A0%E4%B8%89
 }

Servlet容器对获取的参数处理 

如上面的例子,浏览器对“张三”进行了UTF-8的编码处理。在Servlet中获取这个参数,如使用:reqeest.getParameter("name")。如果容器默认使用的是的是ISO-8859-1编码,就相当于做了以下操作。

public static void main(String[] args) throws Exception {
        String text2=URLDecoder.decode("%E5%BC%A0%E4%B8%89","ISO-8859-1");
        System.out.println(text2);
        //输出:å¼ ä¸
    }

这样就出现了乱码的情况,因为客户端或者说浏览器处的编码方式跟服务端如tomcat的编码方式不同导致的。

下面来说下怎么解决。

换Servlet容器的编码格式

简单的方式是可以改变Servelt容器(如tomcat)的编码方式,这样只要浏览器的编码方式跟容器的编码方式相同,一般不会出现乱码。

tomcat需要修改根目录下的conf/ser.xml文件

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

改成

<Connector port="8080"  protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />

在tomcat7以及之前,其默认编码方式都是“ISO-8859-1”,在tomcat8后默认编码方式使用的都是“UTF-8”,所以如果使用tomcat8+,而浏览器也是UTF-8的编码格式,一般不需要修改。

下面看看,浏览器的编码格式。

浏览器对POST和GET请求方式不同的编码处理

如果不修改Web容器的的默认编码格式,而在Servlet中处理乱码问题需要区分POST请求和GET请求。

1、POST请求

上面的例子中,使用的是GET请求,他是将参数直接放在url后面进行拼接的,使用一个“?”进行分割。而POST请求会将参数放在request body中,根据Content-Type对数据进行编码(如浏览器可以设置Content-Type:text/html;charset=UTF-8),然后再把表单数据发送给服务器。

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

这时候如果容器使用“ISO-8859-1”或其他的非“UTF-8”的解码方式,就会发生乱码的情况。

这时候可以使用HttpServletRequest的setCharacterEncoding()方法来指定获取POST请求参数时使用的编码。

如浏览器如果使用“UTF-8”发送的POST请求,在Servlet的时候可以使用request.setCharacterEncoding("UTF-8");来规定获取参数的时候使用的编码方式(如果容器默认是ISO-8859-1)。

注意:这个方法一定要在获取请求参数之前执行才会生效,如果先获取参数,再执行setCharacterEncoding("UTF-8"),那么还是会根据TOMCAT容器的默认编码方式来进行节码。

2、GET请求

上面的setCharaCterEncoding()方法只对Request Body中的参数才有用。但是使用GET发送的请求,参数是在url中的(因为处理URL的是HTTP服务器,而不是Web容器,tomcat中只是内嵌了一个Http容器),所以还是会使用tomcat的默认编码来转换。

这时候可以使用String的getBytes()来处理。如浏览器使用UTF-8处理字符,而Web容器使用的时ISO-8859-1。

String name=request.getParameter("name");
name=new String(name.getBytes("ISO-8859-1"),"utf-8");
//这个name就是正确的值了

如果不确定浏览器的编码格式,通常可以使用jquery或者javascript来将非ASCII的参数按指定的格式进行转码,然后组到url后面作为参数。

返回也是一样的。处理好返回的编码格式跟浏览器的解析格式就不会出现乱码问题了。。。。

参考:传送门1、《JSP&Servlet学习笔记》、


end...

猜你喜欢

转载自www.cnblogs.com/Eastry/p/12452408.html