当我们在直接在servlet中用reponse.getWrite()直接往浏览器打印消息时,发现打印出来的消息是???等乱码,那么通常是由于我们服务器的编码与浏览器的编码不同所引起的。也就是说服务器客户端编码不一致。因为英文字符是占一个字节的,但是中文占两个字节,所以有一些解码方式就会把我们发送的中文改成另外一个样子。相当于一个字被拆成两半了,那肯定和原来的不一样了。
我们常用的服务器Tomcat,它默认的是iso8859-1,是不支持中文的,所以我们浏览器和服务器之间传中文的的时候,就会出现一些乱码的错误。
所以,首先我们要检查一下当前浏览器的编码,在浏览器的开发者模式下的Console控制台中输入
document.charset
就能看到当前网页的编码。记住我们tomcat服务器默认的是iso8859-1编码
首先是服务端打印中文的的乱码避免
只要然我们response的编码方式,与浏览器一致即可。
response.setContentType("text/html;charset=UTF-8");
这句话很强大,他不仅设置了我们打印中文时的编码,他还会把我们浏览器的编码也设置成UTF-8;他相当于
先手动设置浏览器的编码方式 +
response.setCharacterEncoding("UTF-8");
然后是通过jsp提交表单但是服务器端接收却是乱码的问题
这也是由于服务器客户端编码不一致导致的,但是这个解决方法可能更加简单一些,如果你是以post方式提交表单的那么只要,这样就能保证服务器会用UTF-8的编码形式对表单中的数据进行处理
request.setCharacterEncoding("text/html;charset=UTF-8");
但是如果是get方法的话,对乱码的处理就麻烦一些,这要从两种传输方式的本质入手,post方式是把数据封装到request对象中,交给服务器的,所以我们只需要设置request的编码方式就好,但是get的提交的数据是从请求行提交过去的。所以仅仅设置request的编码方式是无效的。
所以我们需要更换思路,再知道浏览器编码,先通过浏览器的编码规则先把乱码转回字节数组,再用特定方式对字节数组编码。
如:传过来的数据是name = "小强".
String name = request.getParameter("name");//此时由于IOS8859-1不识别中文,已经乱码
//就是传过来的二进制数据已经被IOS8859-1的编码方式给编好了。
//所以我们对这个name进行反向编码。通过IOS8859-1的编码规则再转成字节数组。
byte[] bname = name.getBytes("iso8859-1");
//然后把得到的二进制字节数组再进行编码即可。毕竟本来数据也是以二进制的形式传输的。
String finalname = new String(bname,"UTF-8");
也可以直接简写成
String old = request.getParameter("name");
String name = new String(old.getBytes("ISO-8859-1"),"UTF-8");
当然也有更暴力的方法,直接把tomcat等服务器的编码方式设置的和浏览器一样,在tomcat的config目录下的server.xml中的Connector标签中,加上URIEncoding这个属性,并把值设置为UTF-8。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
当然,这种方式感觉起来总是怪怪的,所以嘛,为了方便,我们最好就用post的方式发送数据就好了,还保证了数据传输的安全性。