Tomcat/JSP中文编码配置
来源:http://blog.csdn.net/zhangzikui/article/details/6169978
http://www.iteye.com/topic/300656
第一 java源代码文件编码
保存文件必须以一种编码存;读文件也必须以一种编码读,如不特别设置,去系统默认的编码,中文windows为GBK编码。
从.java->.class过程是,先编写.java文件并按某种编码方式保存,然后用javac方法编译此文件,注意如.java没按系统默认编码保存则要带encoding参数指明实际编码,否则出错,生成的.class文件存为系统默认编码。
从.jsp->.java->.class,先存为某种编码的.jsp文件,然后tomcat根据pageEncoding读取并转化为servlet存为系统默认编码,然后同上面.java->.class过程。
第二eclipse开发环境对源代码文件编码的影响
IDE的encoding为对系统下文件打开的解码方式或保存的编码方式。特例:如果.jsp文件有<%@ page language="java" pageEncoding="UTF-8"%>,则eclipse会自动存为UTF-8方式,不管eclipse的encoding是什么,这也是eclipse的聪明之处。
第三 jsp源代码文件编码
pageEncoding="UTF-8"表示此文件的编码方式,必须与此文件存储方式一致(所以eclipse会首选根据它来存文件),
<%@ page language="java" pageEncoding="UTF-8"%> 表示JSP文件编码方式,web容器tomcat根据这个来读此.jsp文件并编译为servlet。
第四 servlet生成html文件编码方式
<%@ page contentType="text/html;charset= “UTF-8"%>
contentType="text/html;charset=UTF-8"表示当浏览器得到此文件时以什么方式解码。例:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=iso8859-1"%>
<html>
<head>
<title>test</title>
</head>
<body>
我是个好人
</body>
</html>
会产生乱码,因为存为UTF-8的文件被解码为iso8859-1,这样 如有中文肯定出乱码。
至此,页面应为:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<title>中文问题</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
我是个好人
</body>
</html>
第四,request与response编码设置方式
request.setCharacterEncoding("UTF-8")是把提交内容的字符集设为UTF-8
response.setCharacterEncoding("UTF-8")可以把页面中的<%@ page contentType="text/html;charset=iso8859-1"%>
第五,java连接数据库编码
1、mysql配置文件:
修改mysql在windows/my.ini里default-character-set=utf-8
2、mysql里数据库和表也都设为utf8_unicode_ci
3、数据库连结:jdbc:mysql://localhost/mydb?useUnicode=true&characterEncoding=utf-8
注意,关键就在于此:此句中间是'&'不是'&'这是因为数据库连结时,在.jsp和.java文件中应该用&号,而XML文件中需要用&
对于Web容器来说,如果你不设置,默认是ISO8859-1
String des = new String(s.getBytes("iso8859-1"),"UTF-8");都可以使用这个 不论哪里,有乱码就是用
第六页面请求的编码(表单的get提交、表单的post提交、页面链接传递中文参数、地址栏中参数直接输入中文提交)
请求响应的全过程:
浏览器 IE/FireFox ----------->Servlet容器------------------------>显示页面
编码 使用容器的URIEncoding转码 解码
换为charset=UTF-8,是给告诉浏览器我这个文件的编码方式。
一共四种方式:表单的get提交、表单的post提交、页面链接传递中文参数、地址栏中参数直接输入中文提交。
无论何种表单提交都可以在后台的java文件中通过String des = new String(s.getBytes("iso8859-1"),"UTF-8");来转换成你想要的UTF-8编码方式。
1. 表单get方式提交
浏览器根据页面的charset编码方式对页面进行编码,然后提交至服务器,首先进入对应的字符编码过滤器(如果有的话),不过Tomcat6.0对于get提交方式采用的是server.xml文件中的URIEncoding编码方式,而并不会采用过滤器中设置的编码,那么根据我的环境设置,jsp页面都使用UTF-8的编码,Servlet容器的URIEncoding也设置为UTF-8,则servlet不用进行转码即可正确解码,获得正常的中文字符串。那么,响应页面的中文因为页面的统一编码(UTF-8)自然也会正常显示。当然,如果我们Tomcat的URIEncoding设置为其他非UTF-8的编码方式时,页面的内容进入Tomcat解析时,因为Tomcat和页面的编码不统一,就需要转码。例如,如果我们采用Tomcat默认的ISO-8859-1,那么当我们使用request.getParameter("yourVariable ")获取表单参数值时其实Servlet就进行了转码,方式为UTF-8-->ISO-58859-1(我的页面charset都是UTF-8),类似于这样
new String(变量值.getBytes("UTF-8"),"ISO-8859-1");
例如表单的username属性以字符串"编辑"提交,那么进入容器后,FormBean中的这个变量会乱码,request.getParameter(username)一样的效果,s1就是request返回的结果,下面是内存快照。
不过即使这样,我们依然可以使用不恰当的方法显示正常的中文,即逆向转码,例如上面的乱码,我们可以通过ISO8859-1-->UTF-8这种方式还原我们提交时的中文。以下是GBK,UTF-8,ISO-8859-1三者之间互相转换的内存快照:
我们可以看到,偶数汉字可以在UTF-8,GBK两者中互相转换,而奇数个汉字则不能。综上看来,貌似Tomcat的URIEncoding设置为UTF-8是最好的解决办法,不过这样的设置依然无法解决上面我所说的第三、第四种情况。大家继续向下看。(这里有一点我不确定,就是页面提交至Servlet容器时,是以页面的charset方式编码后直接进入容器,还是以charset转码为ISO-8859-1方式进入,大家有什么见解?)
2.表单的post提交
对于这种方式的请求,request.setCharacterEncoding("一般来自于web.xml中过滤器设置的参数")方法进行编码设置将会产生作用,struts的表单提交方式默认为post方式,那么按照上面我的环境设置,页面,容器,都采用UTF-8编码方式,就不会产生中文乱码问题。
程序加上org.springframework.web.filter.CharacterEncodingFilter过滤器.
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
因为规范要求浏览器提交数据都要用utf8编码,所以这里设置编码方式为UTF8.
特别注意:
a,这个过滤器只是简单的调用:request.setCharacterEncoding(this.encoding);
在这个语句之前不能调用任何的request.getParameter()方法,否则会设置tomcat的缺省字符集为"ISO-8859-1",并且使setCharacterEncoding的调用失效.所以在这个过滤器之前的过滤器中不能有对getParameter这类方法的调用,比较安全的做法就是把这个过滤器尽量靠前放.
b,在server.xml中不能加上<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
这个value也设置tomcat的缺省字符集为"ISO-8859-1",使setCharacterEncoding的调用失效.可能其他的value也有这个问题,我没有测试过.
如果要观察http请求参数,可以考虑用抓包工具,例如ethereal或者wireshark
3.页面链接中传递中文参数
我虚拟一个这样的场景,请求页面中有如下代码
Html代码
<%
String username = "编辑";
%>
<a href="hello.do?username=<%=username%>">页面中链接传递中文</a>
对于这种方式,我们需要先将参数使用统一的编码方式编码,将编码后的字符放入链接,这里我对参数以UTF-8方式编码,如下
<% String username = java.net.URLEncoder.encode("编辑","UTF-8"); %>
那么这样我们也不会产生中文乱码问题
如果是页面超连接连接中带的汉字,则编码根据页面编码的不同而不同,如果页面的
content="text/html; charset=utf-8",则在tomcat/conf/server.xml中的配置文件中:
<!-- Define a non-SSL Coyote HTTP/1.1 Connector on port 8080 -->
<Connector port="8080"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000" useBodyEncodingForURI="true"
disableUploadTimeout="true" />
加上:useBodyEncodingForURI="true"即可正常使用getParameter取出正确内容.
如果content="text/html; charset=GBK",需用
new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK")
取出,其他情况类似
4. 地址栏中参数直接输入中文提交
从地址栏直接输入汉字,则一般编码为"GBK",需要用
new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK") 取出
例如浏览器地址栏中输入"http://localhost:8080/helloapp.do?username=编辑"提交,对于这种方式,浏览器不会采用页面的charset方式对URL中的中文进行编码后提交至服务器(IE,FireFox都一样),而是采用系统的GBK转码为ISO-8859-1之后提交至Servlet容器,那么,如果对于前三种方式我们所做的设置,在这里就有问题了,因为进入容器时中文进行了GBK至ISO-8859-1的转码,而之前我们的Servlet容器URIEncoding设置为UTF-8,当我们使用request.getParameter("username")时,相当于又进行了这样的流程GBK-->ISO-8859-1-->UTF-8,按照以上我们使用的测试中文,“编辑”,使用request.getParameter("username")则会得到这样的结果�༭,下图是进行转码的内存快照:
我们可以看到“编辑”经过从GBK-->ISO-8859-1-->UTF-8的过程后得到的就是�༭这样的结果,这里我们还会想到那进行2次逆向转码看看,不过可惜的是,结果为“锟洁辑”。对于这种情况,我们的解决办法就是,Tomcat的URIEncoding采用默认的ISO-8859-1字符集,那么我们可以在程序中通过ISO-8859-1-->GBK这样不恰当的逆向转码方式得到正常的中文“编辑”,但这样的结果是,我们get请求方式的中文处理解决办法就需要改变。如,在我的环境下就需要进行ISO-8859-1-->UTF-8的转码,挺不爽。
综上,对于乱码问题,前三种方式是一般用户的请求方式,第四种属于非正常途径的请求方式,对于这种方式产生的问题我认为无法很好的解决,也不需要解决。我看到javaeye对于这样的情况就没有处理,不知道大家在自己的项目中是如何处理的?我的实验是,IE6的设置会影响应用路径的编码方式,例如地址栏中请求一个中文JSP页面,如:http://localhost:8080/helloapp/编辑.jsp,IE默认是勾选"以UTF-8发送URL"项的,那么按照我上面总结的处理方式,这个请求可以正常显示页面,如图:
如果取消IE的这个选项,那么浏览器会以GBK编码应用路径的中文,得到的结果如图:
按照我上面的设置,这里如果将Tomcat的URIEncoding设置为GBK,则也可以正常显示页面。对于FireFox3.0,则是以UTF-8编码。
总结:
1,所有页面使用utf8编码,
2,服务器加上过滤器,
3,server.xml中不要使用
<Valve className="org.apache.catalina.valves.RequestDumperValve"/>
4,server.xml文件加上useBodyEncodingForURI="true"
这样应该可以搞定大多数前台的中文问题.至于地址栏输入中文,不支持也罢,一般的程序很少要求
从这里输入.
Tomcat/JSP中文编码配置的更多相关文章
- Tomcat+JSP经典配置实例
经常看到jsp的初学者问tomcat下如何配置jsp.servlet和bean的问题,于是总结了一下如何tomcat下配置jsp.servlet和ben,希望对那些初学者有所帮助. 一.开发环境配置 ...
- JDK - Tomcat - JSP - Servlet 配置运行全攻略(转)
http://www.cnblogs.com/myqiao/archive/2005/08/29/225497.html 花了将近两个月的时间,从 JDK 开始一步一步摸索,历经千辛万苦,终于让第一个 ...
- Windows下Apache+Tomcat+jsp+php的服务器整合配置经验总结
对于Apache+Tomcat+jsp+php的整合,针对不同的Tomcat和apache的版本,稍微有些区别. 一.所需软件 (1)JDK: jdk-7u15-windows-x64.exejdk的 ...
- Tomcat虚拟目录配置方法及原理
tomcat 安装好之后,只需要把你的程序包放到$Tomcat_Home$/webapps下就可以直接使用了.这样会使webapps越来越大就需要设置虚拟目录: 1.单个应用设置: 在<Host ...
- tomcat 的优化配置
一.关于并发连接量的配置 在tomcat的server.xml配置文件中:将<Connector port="8080" protocol="HTTP/1.1&qu ...
- Tomcat server.xml配置示例
本文由 ImportNew 几乎所有容器类型的应用都会包含一个名为 server.xml 的文件结构.基本上,其中的每个元数据或者配置都是容器完成初始化所需要的.正是由于这些内容都是可配置的,使得软件 ...
- Tomcat免安装配置
大家都知道tomcat吧!因为Tomcat 技术先进.性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器,也是运行Servlet和JS ...
- window xp Apache与Tomcat集群配置--转载
转载地址:http://www.cnblogs.com/obullxl/archive/2011/06/09/apache-tomcat-cluster-config.html 一. 环境说明 Win ...
- java:jdk环境变量配置+tomcat环境变量配置
一:JDK1.先安装jdk 查看jdk版本: DOC下输入java -version2.配置环境变量(添加系统变量) JAVA_HOME D:\study\jdk-6\jdk-6(j ...
随机推荐
- 初识WEB:输入URL之后的故事【转】
转载一篇文章,分析的是浏览器输入url后所执行的一系列操作!写得非常清晰易懂,分享给大家! 作者:Jesse 出处:http://jesse2013.cnblogs.com/ 本文版权归作者和博客园共 ...
- PlayFramework 1.2.x 在Controller 中识别JSON提交
链接 http://stackoverflow.com/questions/6132892/consuming-json-in-play-framework-controller @Global pu ...
- cocos2dx的lua绑定
一.cocos2dx对tolua++绑定的修正 A.c对lua回调函数的引用 在使用cocos2dx编写游戏时,我们经常会设置一些回调函数(时钟.菜单选择等).如果采用脚本方式编写游戏的话,这些回调函 ...
- python watchdog
监视文件变更 #!/usr/bin/python # -*- coding:UTF-8 -*- import time from watchdog.observers import Observer ...
- 从function前面的!想到的
最近没事喜欢看看,一些js库的源码,结果发现库前不是加一个!就是加+或者一个(),心中猜出个大概知道这个是让函数自动执行,可是这么多符号达到同一个目的,原理是什么呢,下面做一下剖析: 先从IIFE开始 ...
- 使用nodejs搭建图片服务器(一)
背景 当我们开发一个Web项目的时候,为了将图片管理与web服务分离开,通常都会搭建一个图片服务器. 之所以选择nodejs是因为使用nodejs来搭建web项目相当简单而且快速,虽然这个图片服务器很 ...
- 解析表达式到lucene.net的Query
查询的时候有自己的查询格式,为了统一并且方便的搜索lucene.net 于是就写了个解析格式,大体上覆盖了几乎所有的lucene.net的query了.当然少了公共扩展库里包含的regexQuery, ...
- 【NS2仿真】UDP协议
# # cbr # \ # udp sink # \ / # n0--------5M 2ms---------n1 # # set ns [new Simulator] set f [open ou ...
- MySQL工具汇总
本博客已经迁移至:http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文请点击:http://cenalulu.github.io/mysql/mysql-tools-lis ...
- redis实现有序的消息队列
redis是什么东西就不多说了,网上文章一搜一大堆. 首先来说一下我要实现的功能: 类似一个消息中转站吧,如果有人要发送消息,先将消息发到我这里来,然后我这边进行转发,为的就是有一个统一的管理和修改时 ...