`
ASCII
  • 浏览: 30882 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

tomcat编码问题根源-2

阅读更多

    3.2. 转换过程的参数设置
    在以上的转换过程中可以看到,new String(code, "GB2312");这一处的第二个参数非常重要,它告诉java,这个字符串的原始编码是什么,如果写成其他的编码,必然会发生错误。

    因此,转换过程中的参数,java必须有途径得知正确的参数。 
    举例说,让java从文本文件里面读取一段中文。Java最终得到的字符串肯定是Unicode的,但是它需要程序员告诉它,这个文本文件到底是GB2312的,还是UTF-8的。如果程序员不告诉它,它就会贸然选择一种编码,进行解释,其结果可能就是乱码了
又举例说,如果一个Servlet得到了一个http的请求(request),需要程序员告之,这个请求里面的字符串是UTF-8,GB2312,还是纯粹的英文?当然,在得不到信息的时候,它又会自己胡乱猜一个。

    怎么?你不记得自己在代码里面指定过?对了,也许这就是中文问题的原因。 
    多数应用平台(应用服务器或其他)都不是关心中文问题的人编写的,所以不同的应用平台之间,设置参数的方式并不一样,可以说千奇百怪,甚至根本错误。

    在最新版本的tomcat上,推荐的处理方法涉及4个参数
    1. 网页必须制定http content type
    2. JSP必须制定JSP content type
    3. servlet/jsp的请求,必须设定字符集request.setCharacterEncoding.
    4. 修改tomcat的server.xml文件中URIEncoding的设置
    正如文章开头提到的,不同应用服务器 的方式并不一致。前3个参数都是规范规定的,而第4的参数并没有规定,所以不同的服务器要用不同的方法。比如tomcat4不需要这个参数,它会直接使用参数3。

    有人认为修改tomcat的配置文件麻烦,而自己写转码的函数进行处理,这不是一个很好的方法,如果转换服务器,因为服务器本身的处理方式变化了,这段“转码”函数很有可能得到面目全非的结果,比如在tomcat4上。

    这里面似乎存在很多重复,但是没有办法。有时候给一段字符给java,java确实没有办法猜测其字符集。如参数3本来是没有的,J2EE规范认为浏览器提交的数据会描述数据的字符集,但是实际上没有浏览器遵守,所以才不得不引入这个参数。 

    4 . 中文问题的非技术原因
    以上分析了中文问题出现的技术原因,除此以外,还存在两个不是纯技术方面的因素

 

    4.1. 错误做法的信心从何而来
    早在几年前的tomcat3年代,网上流传的种种解决方法中,就有一种声称不能给JSP指定字符集,否则会造成乱码。这是一个很奇怪的说法,似乎SUN设计的机制完全错误一样,但是何以有不少人相信并且深受其害呢?
因为中文编码本身的特性,有时候几个错误的操作,反而会得到似乎正确的结果。
比如,“中”的GB2312编码有两个字节D6 D0
    1. 如果要把它作为ISO8859-1来处理,实际上是对应两个字符的,即Ö 和Ð。
    2. 如果不指定用户提交数据的字符集,tomcat会以为提交的是这两个字符。
    3. 经过tomcat处理之后,再次输出到相应页面,tomcat当然仍然以ISO8859-1的方式输出两个字符Ö 和Ð
    4. 这样,客户端得到了ISO8859-1的ÖÐ,也就是和GB2312的“中”一样的两个字节。因此他会觉得,自己提交的数据被正确的处理了。

    实际上这样的做法是非常危险的
    首先,这个时候在tomcat的内部,代表这个数据的String的值不是Unicode的“中”,而是Unicode的Ö和Ð也就是4个字节(不要忘记,java的字符串既不是ISO8859-1,也不是GB2312),尽管把这两个错误的字符转为ISO8859-1的字节输出后得到了似乎正确的结果,但是如果系统中还有其他不是来自于用户输入的字符串呢?比如说来自于数据库?tomcat如果把正确的字符串按照同样的方法处理,自然就会造成乱码。
其次,因为String的内容并不是应用程序要处理的内容本身,甚至连长度都变了,所以很多字符串操作都会出现莫名其妙的错误。

    最简单的例子:
    下载最新的tomcat,运行
    1. 访问 http://localhost/servlets-examples/servlet/RequestParamExample
    2. 点击右键把字符集改成GB2312
    3. 分别在两个框输入中 文
    4. 提交
    5. 得到一个显示乱码的页面(左)
    6. 再点击右键把字符集改成GB2312
    7. “中文”两个字出现了(右)

    结果似乎正确,除了要手工改浏览器字符集以外(某些版本的浏览器并不需要)。但是只要使用调试器,或者直接在代码中打印用户输入的字符,就可以看到,得到的用户输入不是“中文”,而是ÖÐ ÎÄ。
这就是为什么有些应用程序“界面显示正确,但是控制台打印的都是乱码”的原因。当你知道自己看起来正确的系统中正在运行着这些奇怪的字符的时候,该考虑放弃这些错误的“捷径”了

    4.2. 并不可靠的工具和 服务器
    习惯上,我们总是认为我们使用的开源工具或者商业服务器 是正确的,起码是没有大问题的。这个假设在很多时候正确,但是在中文问题方面,并非如此。别忘了多数软件 的作者都是欧美人,他们中的很多并不懂也不关心中文或者其他双字节字符集的问题。因此有些工具或者应用服务器在中文处理方法上模糊不清,或者根本错误(真正可怕的是某些国产商业软件都是错误的)。
    这给我们的工作增加了很多难度,因为你的代码在别人的应用服务器上运行,有时候你必须适应他们代码里面的错误。
有很多工具有提供所谓的转码功能,在你弄清楚它到底是做什么之前,不要贸然使用,起码要做一个备份。已经有不少人使用这种“电子碎纸机 ”杀死了自己的中文数据。
就连java的规范本身,也存在漏洞,比如String.getBytes()这个函数。其设计就是根本错误的,尽管新版的jdk已经声明废止这个函数,但是很多人还在使用。又如URI的编码方式,servlet规范并没有指出应该如何设置,这才导致了tomcat实用自定义的URIEncoding参数。

    5. 小结
    作为一般的应用开发者,没有必要去深究中文字节的每个转换过程。但是,我们需要记住,中文存在很多种形式,而Java如何处理这些形式,需要程序员告知。
简单的说,最可靠的处理办法,就是保证中文在每一个环节都正确。这并不是废话。如果程序员严格按照规范的推荐,设置所需要的各种参数,最后即使遗漏了什么,也是很容易找到原因的。相反,如果走所谓的捷径,有意的疏漏或者错误设置字符集,或用大串的getBytes()进行可疑的转换,也许可以得到似乎正确的结果,但是当问题出现的时候,就很可能成为死结了。

分享到:
评论

相关推荐

    彻底解决 Tomcat 5 下文字乱码问题 - JSP日志 - ※一路风尘※

    然而,在实际操作中,开发者时常会遇到字符编码问题,尤其是在Tomcat 5这样的较旧版本上。本文将深入探讨如何解决Tomcat 5中的文字乱码问题,尤其是针对JSP日志的处理。 首先,我们要理解乱码问题的根源。乱码通常...

    Tomcat乱码问题

    在使用Tomcat服务器部署Web应用时,字符编码问题时常困扰着开发者,尤其是在处理中文或特殊字符时,页面显示出现乱码是常见的现象。本文将深入探讨Tomcat乱码问题的原因,并提供一系列有效的解决方案,帮助你彻底...

    tomcat 异常

    当遇到“Tomcat异常”时,通常意味着在运行或配置Tomcat时遇到了问题。下面将详细讨论相关知识点: 1. **Tomcat异常类型**: - `NullPointerException`:这是Java中最常见的异常,表示尝试访问一个null对象的属性...

    Hibernatetools编码格式的问题

    标题 "Hibernatetools编码格式的问题" 涉及的是在使用Hibernate Tools时遇到的编码相关问题。Hibernate Tools是Hibernate框架的一个扩展,它提供了一系列的辅助工具,如逆向工程(将数据库模式转化为Java实体类)、...

    Tomcat服务器图片地址中文路径问题解决办法

    总的来说,理解和解决Tomcat服务器的中文路径问题,关键在于理解URI编码和解码的过程,以及服务器和浏览器之间的编码约定。通过调整服务器配置,我们可以确保Tomcat能够正确处理包含中文字符的URI,从而保证应用的...

    JSP中文乱码问题完全处理方案.docx

    问题的根源在于编码格式的不一致或默认编码不支持中文字符。JSP默认使用ISO-8859-1编码,而中文字符通常使用GBK、GB2312或UTF-8编码。本文档提供了JSP中文乱码问题的全面解决方案。 首先,我们来看**JSP页面中文...

    浅谈Tomcat乱码与端口占用的解决方案

    综上所述,通过调整字符编码解决乱码问题以及通过端口检测和管理解决端口占用问题,是确保Tomcat服务器正常运行的两个关键点。在日常的工作中,我们需要对这两个问题保持足够的警觉,并及时采取适当的措施进行应对。...

    Java开发乱码问题解决方法汇总

    乱码问题的根源之一是项目中的编码方式不统一。因此,在项目中统一使用一种编码方式是非常重要的。例如,在Eclipse中,可以右键点击项目,选择Properties,设置项目的文本文件编码方式为UTF-8。 2. 设置web.xml编码...

    java中文乱码终极处理方案.docx

    不过,实际上,很多问题的根源并不在于编程语言或框架本身,而是对编码和文件处理的误解。本文将深入探讨如何解决Java中的中文乱码问题。 首先,我们要理解编码的基础知识。常见的字符编码有UTF-8、GBK、GB2312和...

    Java编程技术中汉字问题的解决

    在Java编程技术中,处理汉字或任何非英文字符集时,常常会遇到编码问题,这主要是因为不同的系统、软件或网络环境可能采用不同的字符编码标准。例如,在Web开发中,客户端浏览器、服务器端以及数据库之间如果编码不...

    Jsp和Servlet中文乱码问题

    2. **JSP页面自身编码设置问题**:JSP页面的编码设置(如`; charset=UTF-8" pageEncoding="UTF-8"%>`)如果不正确或与实际使用的编码不符,也会引发乱码。 3. **Servlet中的编码处理不当**:在Servlet中读取请求...

    struts2上传下载 解决中文文件名乱码

    Struts2文件上传组件在处理文件名时,如果不进行适当的编码设置,也会出现同样的问题。 解决这个问题的关键步骤如下: 1. **配置Struts2拦截器**:Struts2的文件上传拦截器(`org.apache.struts2.interceptor....

    javaweb servlet(jsp)的乱码问题原理及解决

    ### javaweb servlet(jsp)的乱码问题原理及...需要注意的是,编码问题的根源在于不同组件间编码设置的不一致,因此在设计和实现时需充分考虑编码兼容性和统一性,确保数据在整个传输过程中都能正确地被解码和呈现。

    web项目乱码问题 jsp乱码问题解决

    当表单数据以POST方式提交时,Tomcat默认使用iso8859-1编码处理请求参数,而接收端JSP可能期望的是UTF-8编码,这就需要采取措施进行转换。 解决POST提交乱码的方法有以下几种: A. 手动转换:在接收参数时,先将...

    java乱码自己解决的办法

    在Java开发过程中,字符编码问题常常困扰着开发者,尤其是在处理中文等多字节字符时,乱码问题尤为突出。本文将深入探讨Java乱码的根源,并提供一系列实用的解决方案,帮助开发者有效应对这一挑战。 ### Java乱码...

    系统中文乱码解决方案

    - **目的**:设置Tomcat编码以防止GET请求时出现乱码。 - **配置示例**: ```xml URIEncoding="UTF-8" connectionTimeout="20000" maxThreads="150" port="8888" protocol="HTTP/1.1" redirectPort="8443"/...

    jsp中文乱码问题小结

    服务器输出编码时,例如在Tomcat中,设置`URIEncoding="GBK"`可能同时影响了解码和输出编码。虽然具体机制尚不明确,但确保服务器正确处理字符集转换至关重要。 数据库层面,需要确保数据库连接及SQL语句执行时采用...

    JSP中文乱码问题分析及处理方法

    通过这种方式,可以确保所有通过TOMCAT服务器处理的请求和响应都使用统一的编码格式,避免乱码问题的发生。这种方法特别适合于大型项目或需要统一编码标准的场景。 #### 结论 JSP中文乱码问题主要是由字符编码不...

    乱码问题深度分析课题划分

    本文将深入探讨乱码问题的根源、常见场景以及解决策略,旨在为IT从业者提供一个全面的理解框架。 #### 1. 字符集与乱码现象 乱码,通常是指计算机系统或软件在处理文本时,由于字符编码不一致或转换错误,导致显示...

Global site tag (gtag.js) - Google Analytics