乱码产生的原因
不管是request乱码还是response乱码,其实都是由于客户端(浏览器)跟服务器端采用的编码格式不一致造成的。以request乱码为例:浏览器向服务器发送请求,因为浏览器与服务器之间的通信实质上是socket流,所以要先将请求参数(字符)转换成字节,也就是编码过程,服务器接收到请求参数后进行解码(字节转字符),然后封装到request对象中。如果客户端的编码与服务器端的解码不统一,就会导致通过request获取到的请求参数的值是乱码。
乱码出现在这么几个位置上
- 数据传递过程中的乱码
- 数据保存过程中的乱码
- 数据展示过程中的乱码
一、数据传递过程中的乱码
从浏览器发起的访问方式有三种:在地址栏直接输入URL访问、点击页面中的超链接访问、提交表单访问。
第一种访问方式浏览器默认将参数按照utf-8进行编码,后面两种访问方式浏览器是将参数按照当前页面的显示编码进行编码。
所以对于request乱码,只需要在服务器端设置相应的解码格式即可。由于访问方式不同,浏览器对参数的编码格式也不同,为了方便处理,通过超链接和表单的访问也规定必须是utf-8格式,即显示当前页面的编码也要使用utf-8,这样浏览器将统一使用utf-8对参数进行编码。
1、 POST方式属于表单提交,参数存在于请求体中。
request.setCharacterEncoding("utf-8")
这行代码必须出现在从request对象中获取数据request.getParameter(String name)之前设置才起作用。
这个方法只处理请求体中的乱码问题,对请求行中的乱码不起作用。(处理POST请求中的乱码问题)
2、 GET方式提交的参数会跟在请求行中的uri后边。
服务器按照默认的ISO-8859-1进行解码,这时候会出现获取参数会出现乱码,可以修改服务器端对uri参数的默认编码
关于GET请求中的乱码问题,主要是告诉Tomcat服务器请求行中采用什么样字符编码方式,我们可以去修改Tomcat服务器中的server.xml文件,
将server.xml文件中配置端口号的标签末尾添加URIEncoding="UTF-8",(默认没有设置此属性),这样就可以解决GET请求中的中文乱码问题。
原版的server.xml配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
修改后的server.xml配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
useBodyEncodingForURI="true"
URIEncoding="UTF-8"/>
注意:设置元素的属性useBodyEncodingForURI="true",意思是请求体和uri使用相同的编码格式。useBodyEncodingForURI默认是false,通过设置这两个属性,既可以解决get方式的乱码,又可以解决post方式的乱码。
3、还有一种万能方式处理乱码:
假如参数传送的时候编码方式是ISO-8859-1,我们可以将从request中获取的数据采用ISO-8859-1的方式进行解码,让这个数据再次回到正常的byte[]数组状态,然后再采用一种支持中文的编码方式进行编码,这种方式是一种万能的方式,适合所有的情况。但是前提是必须知道原先采用的原始编码方式是什么,才能够让我们的数据再回到原始状态(byte[]数组),这种方式的缺点就是太麻烦,如果表单中提交的数据量比较大,编码量也就随着庞大起来。
String parameter = new String(request.getParameter("remarkInfo").getBytes("iso-8859-1"),"utf-8");
二、数据保存中出现的乱码问题
数据保存指的是数据库中的乱码问题,有的时候我们在数据库表中存储的中文无法正常显示,显示为乱码,为什么我们当前的这个ORACLE数据库存储中文不会出现乱码问题呢?因为我们在安装Oracle数据库的时候指定了字符的编码方式是支持简体中文的。大家以后在使用MySql数据库的时候,安装之前必须手动设置该数据库采用的字符编码方式,如果采用MySql数据库默认的字符编码方式的话,是会出现中文乱码问题的。大家一定要注意手动修改MySql数据库的字符编码方式。还有一种情况本身数据库是支持简体中文的,但是在保存之前数据已经是乱码,保存之后必然还是乱码。
三、数据展示过程中的乱码
假如服务器发给浏览器的数据默认是按照ISO-8859-1编码,浏览器接收到数据后按照默认的字符集进行解码后显示,如果浏览器的默认解码字符集不是ISO-8859-1,就会出现乱码。对于response乱码,只需要在服务器端指定一个编码字符集,然后通知浏览器按照这个字符集进行解码就可以了。
有三种方式,我一般使用第三种就够了:
1、 //设置服务器端的编码,默认是ISO-8859-1;该方法必须在response.getWriter()之前进行设置
response.setCharacterEncoding("utf-8");
//通知浏览器服务器发送的数据格式
response.setHeader("contentType", "text/html; charset=utf-8");
2、 //设置服务器端的编码
response.setCharacterEncoding("utf-8");
然后在浏览器使用utf-8进行解码
3、 //通知浏览器服务器发送的数据格式
response.setContentType("text/html; charset=utf-8");
一般可以这样做,以防万一:
A、设置服务器端的编码
response.setCharacterEncoding("utf-8");
B、通知浏览器服务器发送的数据格式
response.setContentType("text/html;charset=utf-8");
C、浏览器使用utf-8进行解码
四、JSP页面设置UTF-8
jsp页面顶部添加
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
jsp页面<head>标签里面添加
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">