用户从浏览器端发起一个 HTTP 请求,需要存在编码的地方是 URL、Cookie、Parameter。服务器端接受到 HTTP 请求后要解析 HTTP 协议,其中 URI、Cookie 和 POST 表单参数需要解码,服务器端可能还需要读取数据库中的数据,本地或网络中其它地方的文本文件,这些数据都可能存在编码问题,当 Servlet 处理完所有请求的数据后,需要将这些数据再编码通过 Socket 发送到用户请求的浏览器里,再经过浏览器解码成为文本。
一次 HTTP 请求的编码示例
URL 的几个组成部分
以下测试指定web服务器为Tomcat6.X,浏览器为IE8.X和chrome15.X
准备:
1.下面的汉字以“中”为例,分别对应的各种字符集的十六进制编码如下:
ISO-8859-1: 3f (ISO-8859-1表示的西欧字母,其中并不包含汉字,这里的3f表示不存在的字符)
GB2312: d6d0
GBK: d6d0
UTF-16: feff4e2d
UTF-8: e4b8ad
2.关于Http请求头的查看
三大主流浏览器都有相应的工具
(1).IE下可以使用ieHTTPHeaders
下载地址:http://www.blunck.info/iehttpheaders.html
(2).Firefox可以使用livehttpheaders
(3).chrome本身就自带开发人员工具,可以很方便的查看
3. 开发人员必须清楚的servlet规范:
(1) HttpServletRequest.setCharacterEncoding()方法 仅仅只适用于设置post提交的request body的编码而不是设置get方法提交的queryString的编码。该方法告诉应用服务器应该采用什么编码解析post传过来的内容。
(2) HttpServletRequest.getPathInfo()返回的结果是由Servlet服务器解码(decode)过的。
(3) HttpServletRequest.getRequestURI()返回的字符串没有被Servlet服务器decoded过。
(4) POST提交的数据是作为request body的一部分。
(5) 网页的Http头中ContentType("text/html; charset=GBK")的作用:
(a) 告诉浏览器网页中数据是什么编码;
(b) 表单提交时,通常浏览器会根据ContentType指定的charset对表单中的数据编码,然后发送给服务器的。
这里需要注意的是:这里所说的ContentType是指http头的ContentType,而不是在网页中meta中的ContentType。
1.在浏览器地址栏里输入:
http://localhost:8080/FileUpload/servlet/FileDownLoadServlet中?filename=中.jpg
在path info和Query String中都指定了汉字
IE8.x Http请求消息
Chrome15.x Http请求消息
我们发现path info中都采用的是UTF-8编码,而Query String确采用了不同的编码方式:IE8.x采用的是GBK编码(这边没有正确的显示,至于是什么原因还不清楚),Chrome15.x采用的是UTF-8编码。
浏览器报:
根据上面的错误我们可以很明显的知道,Tomcat服务器没有正确的进行解码,从而找不到Servlet。
了解Tomcat的URL解码:
1.URL 的 URI 部分进行解码的字符集是在 connector 的 <Connector URIEncoding=”UTF-8”/> 中定义的,如果没有定义,那么将以默认编码 ISO-8859-1 解析。所以如果有中文 URL 时最好把 URIEncoding 设置成 UTF-8 编码。
2.GET 方式 HTTP 请求的 QueryString 与 POST 方式 HTTP 请求的表单参数都是作为 Parameters 保存,都是通过 request.getParameter 获取参数值。对它们的解码是在 request.getParameter 方法第一次被调用时进行的。request.getParameter 方法被调用时将会调用 org.apache.catalina.connector.Request 的 parseParameters 方法。这个方法将会对 GET 和 POST 方式传递的参数进行解码。
结果:
我们在Servlet的doGet方法中System.out.println(request.getParameter("filename"))
通过chrome访问的Servlet可以正确的显示汉字,而通过IE访问显示乱码
所有我们这里可以知道Tomcat对QueryString采取的解码方式是UTF-8,下面我们要确认的是Tomcat默认对QueryString采取的编码方式是UTF-8还是因为我们设置的URIEncoding=”UTF-8”?
通过这个实验来说明:首先删除server.xml中指定的URIEncoding=”UTF-8”
在浏览器中输入:
http://localhost:8080/FileUpload/servlet/FileDownLoadServlet?filename=中.jpg
结果:
在两个浏览器中都显示乱码,我们在增加两条输出语句:
new String(request.getParameter("filename").getBytes("ISO-8859-1"), "UTF-8");
new String(request.getParameter("filename").getBytes("ISO-8859-1"), "GBK");
IE在第二条输出语句中显示正确的汉字
Chrome在第一条输出语句总显示正确的汉字
结论:
1.在IE中QueryString部分采用的默认编码方式是GBK
2.Tomcat对QueryString的默认解码方式是ISO-8859-1
3.URIEncoding参数提供了对path info和Query String 部分的解码方式
备注:
new String(request.getParameter("filename").getBytes("ISO-8859-1"), "UTF-8")语句可以获取正确的汉字,原因?
ISO-8859-1 字符集的编码范围是 0000-00FF,正好和一个字节的编码范围相对应。这种特性保证了使用 ISO-8859-1 进行编码和解码可以保持编码数值“不变”。虽然中文字符在经过网络传输时,被错误地“拆”成了两个欧洲字符,但由于输出时也是用 ISO-8859-1,结果被“拆”开的中文字的两半又被合并在一起,从而又刚好组成了一个正确的汉字。虽然最终能取得正确的汉字,但是还是不建议用这种不正常的方式取得参数值,因为这中间增加了一次额外的编码与解码。
2.在已打开的网页上,直接用Get或Post方法发出HTTP请求
以html页面为例
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
作用1:告诉浏览器网页中数据是什么编码;
2: 表单提交时,通常浏览器会根据ContentType指定的charset对表单中的数据编码,然后发送给服务器的。
IE8.X http请求
Chrome15.x Http请求
可以看到QueryString部分都采用了charset设置的UTF-8字符集进行编码
我们可以看看主流搜索引擎百度和Google
可以查看其html源码指定了charset为gb2312
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
可以知道,百度默认使用的编码方式是gb2312,而Google默认是UTF-8
在jsp页面中还可以通过其他方式指定编码,和html页面charset效果一样的设置方式还有
contentType,response.setCharacterEncoding(),response.setContentType(),response.setHeader();
response.setContentType(),response.setHeader();优先级最好,其次是response.setCharacterEncoding();再者是<%@page contentType="text/html; chareset=gbk"%>,最后是<meta http-equiv="content-type"content="text/html; charset=gb2312" />
我们经常设置一个Filter,(此时我们设置前台页面的编码为UTF-8),
(1.并加上如下代码:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
这样我们在Servlet输出参数:
1.System.out.println(request.getParameter("aa");
2.new String(request.getParameter("aa").getBytes("ISO-8859-1"), "UTF-8");
3.new String(request.getParameter("aa").getBytes("ISO-8859-1"), "GBK");
结果:
1正确显示中文,2、3显示乱码,原因:request.setCharacterEncoding对前台的数据进行了解码,所有我们在Servlet中获取参数时不需要再进行解码。
(2.加上如下代码:
request.getParameter("aa");
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
此时的结果是:
2正确显示中文,1、3显示乱码。
原因:前面已经提到” 解码是在 request.getParameter 方法第一次被调用时进行的”,并且此时我们没有在Tomcat中设置URIEncoding属性,默认的解码方式是ISO-8859-1.所以,在request.getParameter("aa");的时候是对UTF-8进行编码的中文用ISO-8859-1进行解码,所有是乱码,此时request.setCharacterEncoding("UTF-8")又对通过ISO-8859-1解码的字符用UTF-8进行解码,所有1结果是乱码。而2刚好可以正确的显示中文,其原因已经在上面解释过了。
总结:出现乱码问题主要是因为编码与解码的字符集不统一造成的,所以对于编码我们自己完全可以指定的我们应该尽量去指定,不要使用默认值,对于浏览器默认设置的我们完全可以动手查看它使用的默认字符集。
UTF-8 在编码效率上和编码安全性上做了平衡,是理想的中文编码方式
补充1:
我们发现不同的浏览器对QueryString采用了不同的编码方式,这就照成了我们服务器端需要对不同的情况进行讨论,其实我们这里可以采取另外一种方式,保证客户端只用一种编码方法向服务器发出请求。
使用Javascript先对URL编码,然后再向服务器提交,不要给浏览器插手的机会。因为Javascript的输出总是一致的,所以就保证了服务器得到的数据是格式统一的
Javascript语言用于编码的函数,一共有三个:
1.escape()虽然这个函数现在已经不提倡使用了,但是由于历史原因,很多地方还在使用它
escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值,对应的解码函数是unescape()
2. encodeURI()是Javascript中真正用来对URL编码的函数。
它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号“; / ? : @ & = + $ , #”,也不进行编码。编码后,它输出符号的utf-8形式,并且在每个字节前加上%它对应的解码函数是decodeURI()
3. encodeURIComponent()。与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。因此,“; / ? : @ & = + $ , #”,这些在encodeURI()中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。
对应的在服务器端我们可以通过:
分别是:
URLDecoder.decode(encodeStr,"UTF-8")
URLEncoder.encode(rawStr, "GBK")
参考:
http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/
- 大小: 10 KB
- 大小: 55.6 KB
- 大小: 1.1 KB
- 大小: 1.6 KB
- 大小: 16 KB
- 大小: 26.5 KB
- 大小: 1 KB
- 大小: 1.5 KB
- 大小: 73 KB
- 大小: 58.4 KB
分享到:
相关推荐
JavaWeb 乱码问题终极解决方案 下面是从给定的文件中生成的相关知识点: 一、确认乱码发生的位置 在解决 JavaWeb 乱码问题时,首先要确认乱码的地方。出现乱码可能是浏览器显示问题,也可能是 Java 编码问题,也...
### 解决Javaweb乱码问题完整方案 在Javaweb开发过程中,字符编码问题经常困扰着开发者,特别是中文等多字节字符的处理。本文将详细讲解如何全面解决Javaweb中的乱码问题,确保网页内容正确显示。 #### 一、配置...
### JavaWeb乱码问题分析与解决 #### 一、引言 在JavaWeb开发中,乱码问题是开发者经常遇到的问题之一。它不仅会影响用户体验,还会对数据的正确性造成潜在威胁。本文将针对请求乱码及响应乱码两种情况进行深入剖析...
在 JavaWeb 技术开发中,中文乱码问题是由于 Java 系统的输入、输出和操作系统的默认编码字符集不一致导致的。 Java 系统内部使用 Unicode 来表示字符,但是在实际应用中,由于应用程序的运行环境不同,和各个本地...
总结来说,解决JavaWeb开发中的中文乱码问题,关键在于正确地设置字符编码。使用`HttpServletResponse`的`setCharacterEncoding`和`setContentType`方法可以确保数据在传输过程中的编码与接收端的解码保持一致,从而...
以下是一些关于JavaWeb中文乱码问题及其解决方案的关键知识点: 1. **字符编码基础**:理解字符编码是解决问题的第一步。常见的字符集有GBK、GB2312(简体中文)、Big5(繁体中文)以及Unicode家族的UTF-8、UTF-16...
总之,解决JavaWeb中的乱码问题需要从多个层面进行考虑:设置过滤器统一请求和响应的编码,确保JSP页面的编码正确,以及在处理文件时注意文件内容的编码。通过这些方式,我们可以有效防止和解决乱码问题,提高应用...
JavaWeb开发技术-解决中文输出乱码问题 ...解决中文输出乱码问题是JavaWeb开发中一个非常重要的问题,需要正确地设置编码方式、处理中文字符的输入和输出,并注意统一的编码方式和浏览器的编码方式。
### javaweb项目中乱码的处理 在Java Web项目的开发过程中,经常遇到的一个问题是字符乱码。这不仅影响用户体验,还可能导致数据错误。本文旨在详细介绍如何解决Java Web项目中的乱码问题,包括如何统一开发环境、...
关于处理Javaweb中中文乱码的问题[收集].pdf
在JavaWeb开发中,页面编码过滤是一个至关重要的环节,它主要解决的是网页中字符编码不一致导致乱码的问题。在给定的标题“JavaWeb页面过滤器之编码过滤”和描述中,我们可以深入探讨JavaWeb中的编码过滤器,以及...
在JavaWeb开发中,字符编码问题常常导致网页显示乱码,影响用户体验和数据处理的准确性。乱码问题的根源在于不同环节(如客户端、服务器、数据库等)对字符集的处理不一致,导致数据在传输过程中被错误地解码。为了...
JavaWeb中字节乱码filter解决办法,其中包括tomcat各个版本进行字符设置.
### JavaWeb开发中的中文乱码问题分析及解决方案 #### 摘要 在JavaWeb开发过程中,中文乱码问题是常见的技术挑战之一。该问题源于不同组件间的编码方式不一致,尤其是在涉及用户输入、数据库交互以及页面展示等环节...
深入分析JavaWeb中文编码问题.doc
解决JavaWeb开发中Jsp存储读取MySQL数据中文乱码的问题.pdf
本项目"解决全站编码问题的javaWeb小项目"旨在提供一套完整的解决方案,确保在项目的各个层面都能正确处理字符编码,从而避免乱码问题。 1. **HTTP请求编码** 当用户通过浏览器发送请求时,请求参数可能包含非...
有关于当安装maven成功后javaweb会出现几个乱码问题,都会解决。 想解决java中文乱码问题也得了解一下我们常用的编码方式: ASCII编码是目前计算机中用得最广泛的字符集及其编码。 ISO8859-1可以表示的是西欧语言。...