`
talentluke
  • 浏览: 604683 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Tomcat处理编码的流程

 
阅读更多

Tomcat是如何处理query/post的编码问题的?
首先我们看看get方式时,tomcat如何获取querystring。
比如我们的url是:http://abc.com/?keywords=%C6%A1%BE%C6    (其中%C6%A1%BE%C6是啤酒的GBK的URLEncode编码)
当请求来到服务器的tomcat(也可以说是Servlet)这一层面时,我们可以通过request获取这个keywords。获取的方式有两种:
(1) 直接使用getParameter("keywords")得到keywords参数
(2) 先使用getQueryString(),再手动解析出keywords参数
我们看看这两种方式。
(1)
getParameter("keywords")
这里涉及 config/server.xml中URIEncode的配置项,
假设我没对tomcat作任何URIEncoding的配置,它默认使用ISO-8859-1的编码。
       当访问http://localhost/?keywords=%C6%A1%BE%C6后,我们试图打印出getParameter("keywords")的值,你猜看到什么?乱码!
我们试图质问tomcat:“为什么是乱码?!
如果我输入的keywords是“啤酒”这样的字符,得到乱码我可以接受,但是我输入的可是“%C6%A1%BE%C6”这样一串ISO-8859-1编码的字符啊!
有人猜测,那是浏览器在搞鬼,浏览器发送的不是“
%C6%A1%BE%C6”这样的可见字符的,而是发送“啤酒”这个非ascii字符(当然,我们应该理解本质上传送的“啤酒”肯定是“啤酒”的某某编码格式的字节码,这个编码可以是常见的GBK或UTF-8)。
但是,其实不是浏览器搞鬼,浏览器发送的就是
%C6%A1%BE%C6”,你可以通过打印request.getQueryString();看到,它输出“keywords=%C6%A1%BE%C6”。
那到底是怎么回事呢?
源于tomcat对表单提交的参数(包括Get方式和Post方式)有个UDecode类的处理过程。什么是UDecode类的处理过程,详细你可以看tomcat源码的UDecode类,这里用简单的一句话概括UDecode类做的事情:修改request中的parameter(包括get方式的url参数的value和post方式的application/x-www-form-urlencoded的参数的value)的字节, 将每1个“%HH”(占3个字节)变成“0xHH”(占1个字节),且将加号"+"(占1个字节)变成空格“ ”(占1个字节)。下面的图直观的描述了这个UDecode过程:

我们看到6个字节的“%D6%D0”变成了2个字节的“[0xD6][0xD0]”,我用中括号“[ ]”来表示其中的内容合起来是一个字节。

     
到这里,我们至少知道了tomcat有个UDecode的过程,所以我们从中推理出这样的一个现象:客户端发送的
keywords参数无论是啤酒的GBK字节码“[0xC6][0xA1][0xBE][0xC6]”还是啤酒的GBKURLEncode字符“%C6%A1%BE%C6”,经过tomcat的UDecode后,到变成前者,即“[0xC6][0xA1][0xBE][0xC6]”。

说到这,我再次问上面一开始的那个问题:
getParameter("keywords")的值为什么是乱码?我给个提示:和UDecode有关!答案现在还不是很明显,但我们脑海可能浮现了这幅图:从UDecode的结果“[0xC6][0xA1][0xBE][0xC6]”到getParameter("keywords")的乱码。

你想到问号的部分是什么吗?很抽象地为你解开答案:


所以,getParameter("keywords")的值为什么是乱码?因为上面的bytes是GBK的字节码,而tomcat错误地将bytes作为ISO-8859-1进行解码了!难怪keywords会是乱码!

这...是tomcat的错吗?坦诚说不是,因为上面“String keywords = new String(bytes,"ISO-8859-1");”中的编码
"ISO-8859-1"是可配置的,大家还记得 config/server.xml中的URIEncode配置项吧?就是这个URIEncode配置项,决定是上面的式子用什么编码。

到了这里,大家都清楚了,设置配置项URIEncode=“GBK”就可以用getParameter("keywords")得到正确的keywords:“啤酒”。

另外配置项useBodyEncodingForURI使得
http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q2
http://confluence.atlassian.com/display/DOC/Configuring+Tomcat%27s+URI+encoding
-------------------------------------------------------------------------------------------------------------------------






现在,我问大家一个问题,当你知道,浏览器无论访问“
http://localhost/?keywords=%C6%A1%BE%C6” 还是 “http://localhost/?keywords=[0xC6][0xA1][0xBE][0xC6]”,tomcat都会将keywords变成“[0xC6][0xA1][0xBE][0xC6]”后,大家觉得要怎么去解码还原keywords为“啤酒”呢?
相信答案大家都很一致:
byte[] bit = new byte[]{(byte)0xD6,(byte)0xD0}; "中"的字节码,是URLDecode之后的字节码
String w = new String(bit, "GBK");  用配置的URIEncoding将其解码,变成字符"中"
String ISOkeywords = request.getParameter("keywords");
String keywords = null;
request.getQueryString();//keywords=%C6%A1%BE%C6
if(StringUtil.isNotBlank(ISOkeywords)){
try {
keywords = new String(ISOkeywords.getBytes("ISO-8859-1"), "GBK");












分享到:
评论

相关推荐

    tomcat字符编码总结

    ### Tomcat字符编码总结 #### 一、引言 在Web开发中,字符编码...总之,理解并掌握Tomcat环境下的字符编码机制,对于提升Web应用程序的质量至关重要。希望本文能帮助开发者们更好地解决实际项目中的字符编码难题。

    修改Tomcat默认编码消除get方式传递参数出现中文乱码

    在处理Web应用程序时,尤其是使用Apache Tomcat作为应用服务器的情况下,遇到中文字符乱码的问题是非常常见的。这一问题通常发生在通过GET方法传递含有中文参数的情况。由于Tomcat默认采用ISO-8859-1编码处理请求,...

    tomcat编码问题

    要解决这个问题,我们需要理解Tomcat处理字符编码的过程,并采取相应的配置调整。 首先,Tomcat默认的字符集可能并不包含GBK,GBK是中国大陆广泛使用的汉字编码标准,它包含了更多的中文字符。因此,当请求参数或...

    apache-tomcat-7.zip 解决了编码问题 和 healder限制问题

    Apache Tomcat 7 在这个版本中可能已经改进了对字符编码的处理,确保输入和输出数据在服务器和客户端之间正确地转换。这可能涉及到HTTP请求的解码,以及响应内容的编码。此外,可能也优化了与Java虚拟机(JVM)的...

    tomcat7,已经设置utf-8编码

    标题 "Tomcat7,已经设置UTF-8编码" 指...总结来说,Tomcat 7已设置为UTF-8编码,意味着它能有效处理多种语言的Web应用,并且提供了稳定的基础环境,使得开发者无需担心字符编码问题,专注于应用程序的开发和功能实现。

    修改Tomcat运行时jvm编码问题

    在IT行业中,尤其是在Java Web开发领域,Tomcat作为一款广泛应用的Servlet容器,有时会在处理字符编码时遇到问题,特别是当系统环境与应用编码不一致时。本文将详细讲解如何修改Tomcat运行时的JVM编码问题,以解决...

    关于\"form表单提交数据编码方式和tomcat接受数据解码方式的思考\"一文的纠错

    在深入理解Tomcat处理编码的机制时,还需要关注Tomcat内部对Servlet请求对象`HttpServletRequest`的处理。`getParameter()`和`getParameterValues()`方法默认使用ISO-8859-1,但可以通过覆盖`ServletRequest`的`set...

    how tomcat work 中文版

    Coyote是Tomcat处理HTTP请求和响应的组件。它监听特定端口(默认8080),接收来自客户端的HTTP请求,解析请求头和请求体,然后交给Catalina处理。处理完成后,Coyote将响应结果打包成HTTP响应,并发送回客户端。 **...

    tomcat 下catalina.out 日志乱码问题处理

    在IT行业中,日志是系统运行过程中的重要记录,它能帮助开发者追踪错误、调试程序以及监控服务状态。Tomcat作为一款广泛应用的Java Servlet容器,其日志输出对于开发者来说至关重要。然而,当遇到“catalina.out日志...

    一个简单url编码解码

    8. **错误处理**:在编码和解码过程中,可能遇到无效的编码序列或编码后的URL。项目应该包含对这些问题的处理逻辑,确保程序的健壮性。 通过这个简单的URL编码解码项目,新手可以深入理解URL编码的基本原理,同时...

    tomcat5.0+JDK1.6环境搭建.doc

    这将确保 Tomcat 5.0 正确地处理中文字符。 Step 3: 指定 Tomcat 5.0 的 JDK 环境 在 Eclipse 中,通过 Window-->Preferences-->MyEclipse-->Servers-->Tomcat-->Tomcat 5.x-->JDK,指定 Tomcat 5.0 的 JDK 环境为...

    tomcat集群配置 程序以及文档

    当我们需要处理高并发、负载均衡或提高应用可用性时,单个Tomcat实例可能无法满足需求,这时就需要进行Tomcat集群配置。本资料包包含了“tomcat集群配置”的程序及文档,提供了现成的例子,帮助我们理解和实践Tomcat...

    apache-tomcat-8.5.53_tomcat的8.0版本_ApacheTomcat8.5_choiceyqj_

    6. **性能优化**:通过改进线程池管理、内存分配策略以及垃圾回收机制,Tomcat 8.5在处理大量并发请求时表现更优。 7. **管理工具**:Tomcat管理员可以使用内置的管理工具,如Manager App和Host Manager,来监控和...

    maven构建的Tomcat源码

    Tomcat的源码可以让我们深入理解其内部工作原理,如请求处理流程、连接器架构、容器设计等。 3. **MyEclipse2014**:这是一个强大的Java集成开发环境,尤其适合进行企业级Java应用的开发。它集成了Maven支持,允许...

    解决Tomcat中文乱码

    当Tomcat处理这些中文内容时,如果没有正确地转换编码,就会出现乱码问题。 #### 原因分析 1. **默认字符集问题**:Tomcat服务器默认采用ISO-8859-1字符集进行编码解码,该字符集并不支持中文字符。 2. **配置文件...

    Tomcat中Get和Post出现乱码的解决办法

    对于 POST 方法,Tomcat 会使用 request.setCharacterEncoding 方法设置的编码来处理,如果未设置,则使用默认的 iso-8859-1 编码。然而,对于 GET 方法,Tomcat 并不会考虑使用 request.setCharacterEncoding 方法...

    编码问题处理

    ### 编码问题处理 在IT领域中,尤其是在Java Web应用开发过程中,字符编码的问题是开发者经常遇到的一个挑战。...对于Java开发者而言,掌握字符编码的基础知识以及如何在开发过程中正确处理编码问题是非常重要的。

    apache-tomcat-8.0.33中文.zip

    Apache Tomcat 8.0.33 在处理请求和响应时,提供了良好的字符集支持,可以有效地避免中文乱码问题。它允许开发者通过配置服务器或应用程序级别的设置来指定默认编码,确保数据在输入和输出过程中保持正确性。 在...

Global site tag (gtag.js) - Google Analytics