前段时间某功能在测试机器上出现乱码,情况如下:
现象:
调试搜索功能时,通过doGet方法提交到后台的中文参数在本地和开发测试机器上为乱码(Action层),在测试人员测试机器上为中文.(Action层)
推断:
怀疑是两台机器(开发人员测试机器,测试人员测试机器)环境不同:1. 先从tomcat查起,在他们各自的tomcat的配置文件server.xml中的Connector标签,有句指定URL编码的配置:URIEncoding="UTF-8" ,开发测试机器上没有配置(默认是IDO-8859-1),测试人员测试机器上配置为GBK,两个配置不同,改成一致(默认),再验证,还是存在乱码;2. 怀疑是系统字符集的问题,用locale命令和查看/etc/sysconfig/i18n 文件查看两台机器的字符集,查看后发现两台机器系统字符集一致,都为UTF-83. 怀疑是apache上有不同的设置,再到apache的httpd.conf上查看,两天的设置基本一致,没有对编码有特殊的设置.4. 怀疑是JVM运行参数的原因.java有一个运行时参数叫做:file.edcoding.这个编码是保存java文件的编码字符集,在调用javac.exe时,JDK用file.edcoding将.java文件读进来,转化为UNICODE放到内存中,所以,这个参数对乱码不会产生影响.从以上可以看出,常规的排查手段已经不能找到原因,所以,从HTTP通信开始下手,从请求发起开始一步步排查,首先,在本地,用到了3个工具,分别是:1. httpFox , Firefox上的一个插件,用来查看所有发起的http请求,内容非常详细.2. membrane-monitor 也是查看http通信的客户端,不依赖浏览器.3. Wireshark 同样是http的抓包工具,他不仅仅可以自己通过各种表达式抓取特定http包,还可以解析tcpdump(后面会说到)抓取的信息(好像tcpdump抓取的是16进制的数据)这次排查三种工具都用到,最简单的是httpFox 使用简单,该有的功能都有,其次是Wireshark,还有很多功能没用到,感觉很强大,而且关键是和浏览器无关,是个很好的分析工具.排查在两个浏览器中进行,IE9和Firefox17,在Firefox下可以看到用DoGET的方式带中文参数请求:
Wireshark 抓取到的信息如下,是UTF-8编码的信息,这步是浏览器自己做的:
在IE9下可以看到用DoGET的方式带中文参数请求:
Wireshark 抓取到的信息如下,是UTF-8编码的信息,这步是浏览器自己做的:
从这里可以看到两个浏览发送中文参数请求的编码方式是不同的.请注意IE里面的高级设置中有这么一个选项:经过试验这的URF8编码,是对URL中的中文例如:www.baidu.com/中文/index.html 中的中文二字进行编码
发送请求后用Wireshark 可以看到,如下图,编码后的部分URL
为了验证,我在服务器上(开发人员测试机器)上又装上了服务器端的http抓包工具,tcpdump,安装过程如下:1、打开网址:www.tcpdump.org/ 下载 libpcap-1.0.0.tar.gz (595.0KB) 软件包,通过命令 tar zxvf libpcap-1.0.0.tar.gz 解压文件,并将其放入自定义的安装目录。2、打开网址:www.tcpdump.org/ 下载tcpdump-4.3.0.tar.gz (867.0KB) 软件包,通过命令 tar zxvf tcpdump-4.3.0.tar.gz 解压文件,并将其放入自定义的安装目录。3.一次到解压目录下:./configure
make
make install即可安装.接着使用命令,将抓取到的信息放到write.log中,tcpdump -X -s 0 -w write.log host xxx.xxx.xxx.xxx and port 80说明下参数:-x 以16 进制数形式显示每一个报文
-s 重定义截取报文大小,默认为96(或68),如果定义为0,则表示获取完整报文
-w 将抓取到的报文放到文件中
host 指定抓取报文的目的地址
port 指定报文目的端口,因为该机器上是apache转发,填apache的端口就可以.
在服务端执行命令后用IE,Firefox下发送请求,将抓取到的文件放到Wireshark中解析,可以看到:
Firefox发送请求时服务端截取的文件:
IE9发送请求时服务端截取的文件:
可以看到和浏览器提交的编码是一致的,所以,可以推断,在浏览器端是编码传输的,并且没有产生所谓的乱码.然后,我在服务端开启远程debug,可以看到在调用以下方法的时候产生了乱码:
但是仔细查看,发现request对象中有个specialAttribute属性,里面以键值对的方式存放了keyword参数,这里的keyword是上图中浏览器编码后的值,所以,在这里是没有乱码的。为什么在调用request.getParameterMap()方法后会产生乱码呢?其实原因和tomcat有关系,在我们调用getParameterMap方法时,request对象会去找WEB容器中的URL编码去解码URL,在Tomcat中指的是在server.xml的以下配置中配置的编码
而开发人员测试机器上没有改配置,即默认使用ISO-8859-1去解码,测试人员测试机器上配置为GBK,即用GBK去解码URL,如果浏览器的编码和tomcat配置文件中配置的编码不一致,就会产生乱码 ,
为了证明我的猜想,我简单加密解密了一段中文,运行结果如下:
这里与我在debug过程中看到的乱码是一致,从而得出结论,乱码的根音来自于tomcat配置文件中设置的URLEncoding参数。
最后,再次总结下:
1. 采用DoGet方式传值,浏览器会帮我们编码,但是各个浏览器的编码方式不一致。
2. 传输过程中,编码后的值不会再被编码。
3. 通过Request对象取参数值时,Request对象会去Web容器中获取URL的编码方式,并用同样的编码区解码URL,如果浏览器的编码和Web容器中的编码不一致,就会产生乱码。
4. 解决方法,在浏览器提交请求前,将中文参数编码两次,浏览器不会再对其进行编码,传到服务端后解码一次即可。
为什么客户端编码两次,服务端解码一次?请看下图:
先声明一个被两次编码以后的字符串,模拟我在浏览器端手动编码的结果,
然后用三种方法对该字符串解码,为什么用三种? 因为这次解码是在调用request.getParameter时
request对象的解码服务端tomcat容器的URLEcoding可能是三种中的一种,可以看到无论是
什么编码方式的解码结果都是一样的,因为这里的配置可能是不一样的,所以要考虑到各种编码方式的可能,这个时候,我们再用代码手动解码一次,就可还原回中文了!
乱码问题就这么解决了,虽然需要手动的解码一次,不过我觉得这个值得,因为乱码后的情况奇奇怪怪,
若觉得每次接么复杂,只需在拦截器端都统一解码就可以,以后不用再担心这个问题.
相关推荐
DOGET和DOPOST中文乱码问题解决方案 DOGET和DOPOST是常用的HTTP请求方法,分别对应GET和POST请求。在Web开发中,中文字符的乱码问题是一个常见的问题,特别是在使用DOGET和DOPOST请求时。今天,我们将讨论DOGET和...
### doGet()方法中文乱码问题解析与解决方案 #### 一、背景介绍 在Web开发过程中,尤其是使用Java Servlet进行Web应用程序开发时,经常会遇到字符编码的问题。其中,“doGet()方法中文乱码问题”尤为常见。该问题的...
我们在javaWeb项目时,使用doget和dopost总是会出现各种原因的中文乱码问题,楼主在查阅大量资料后,将为什么有这样的问题,和如何解决这种问题做个总结。 思维导图: 1. 应答乱码处理(response输出页面时乱码) 1.1 ...
### 解决页面传参中文乱码 在Web开发过程中,特别是在使用Java进行后端开发时,经常遇到的一个问题是中文字符或非ASCII字符在URL参数中的乱码问题。这主要是因为客户端浏览器与服务器之间可能使用的字符集不同导致...
### Java解决GET请求中文乱码问题详解 在Java Web开发中,经常遇到的一个问题是处理GET请求中的中文参数时出现乱码。这个问题主要是因为浏览器发送GET请求时,参数默认使用ISO-8859-1编码格式,而服务器端通常采用...
首先,我们来分析一下JSP中文乱码问题的产生过程。当用户在HTML表单中输入中文并提交信息到JSP页面时,这些信息需要经过多次编码转换才能被存储到MySQL数据库中。如果在任何一个转换过程中字符编码不一致,就会导致...
2. **中文乱码原因**: - **JSP编码**:JSP页面可以保存为不同编码,如GBK或UTF-8,且可通过`contentType`属性指定读取和编译时使用的编码。 - **页面显示**:HTML的`<meta>`标签指定页面编码,影响浏览器如何解码...
### Servlet + Tomcat 中文乱码问题解析及解决方案 #### 一、中文乱码问题概述 在使用Servlet和Tomcat进行Web开发时,经常会遇到中文乱码的问题。这主要是因为客户端(如浏览器)与服务器之间使用的字符编码不一致...
在开发Web应用时,尤其是使用Java技术栈如JSP、Servlet与MySQL数据库交互时,中文乱码问题常常困扰着开发者。这个问题的出现主要是由于字符编码不一致导致的,包括数据库编码、连接编码、页面编码等多个环节。下面...
### MySQL中文乱码问题解决方案 在使用MySQL的过程中,中文乱码问题是经常遇到的一个难题,它不仅影响数据的正确性,还可能对整个系统的稳定性和用户体验造成负面影响。本文将详细介绍如何解决MySQL中的中文乱码...
乱码问题分析与解决策略 页面跳转乱码问题的根本原因在于网络通信中字符集标准不一致,以及应用对国际化支持不完善。解决乱码问题的策略应根据不同的乱码形式来制定。 解决乱码问题的方法通常包括以下几个方面: 1....
在Java编程中,中文乱码问题是一个常见的困扰开发者的问题,特别是在处理输入输出或者网络通信时。这个问题涉及到字符编码的理解和正确使用。以下是对这个主题的详细解析: 首先,我们需要了解字符编码的基础知识。...
MyEclipse中文乱码问题解决方案 在本文中,我们将讨论 MyEclipse 中的中文乱码问题,并提供一个简单的解决方案,不需要任何编码转换。这个解决方案可以直接应用于数据库插入、页面传递或 Servlet 中,解决了中文...
#### 二、乱码产生的原因 乱码主要由以下几种情况引起: 1. **页面本身的编码与浏览器解析编码不一致**:例如页面实际编码为GBK,但浏览器默认按照ISO-8859-1解析。 2. **请求参数的编码问题**:GET或POST请求中...
- **请求乱码**:当用户通过表单提交包含中文的数据时,需要在`doGet`或`doPost`方法中设置请求编码。 ```java request.setCharacterEncoding("UTF-8"); ``` - **响应乱码**:在输出响应内容时,确保响应的编码...
2. 设置请求和响应编码:在Servlet的doGet和doPost方法中,设置request和response的编码为UTF-8,避免在获取请求参数和返回响应时产生乱码。 3. 在数据库连接中设置字符编码:连接数据库时,指定连接字符串中的编码...
### Java插入数据乱码解决集锦 #### 一、Java中文问题的由来及核心问题解析 Java作为一种广泛使用的编程语言,在处理中文等多语言文本时可能会遇到字符编码不匹配导致的乱码问题。这些问题主要源于Java程序在不同...
解决 JSP 和 Servlet 操作 MySQL 中文乱码问题的方法 在 JSP 和 Servlet 操作 MySQL 过程中,中文乱码问题是一个常见的问题,而解决这个问题需要从多方面入手,包括 JSP 页面、Servlet 编程和 Filter 配置等。本文...
### 在Websphere中设置解决中文显示乱码问题 #### 背景介绍 在部署Web应用程序时,尤其是在处理非英文字符集(如中文)的情况下,可能会遇到字符编码不匹配导致的乱码问题。Websphere作为一款广泛使用的应用服务器...