tomcat下中文的彻底解决
这些天开发一个项目,服务器是tomcat,操作系统是xp,采用的是MVC架构,模式是采用Facade模式,总是出现乱码,自己也解决了好多天,同事也帮忙解决,也参考了网上众多网友的文章和意见,总算是搞定。但是好记性不如烂笔杆,所以特意记下,以防止自己遗忘,同时也给那些遇到同样问题的人提供一个好的参考途径:
N Q, I2 | r) Z% N8 j(一) JSP页面上是中文,但是看的是后是乱码:7 t' f* G! @* s
解决的办法就是在JSP页面的编码的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因为Jsp转成Java文件时的编码问题,默认的话有的服务器是ISO-8859-1,如果一个JSP中直接输入了中文,Jsp把它当作ISO8859-1来处理是肯定有问题的,这一点,我们可以通过查看Jasper所生成的Java中间文件来确认; V9 Z% F4 w4 w/ d
(二) 当用Request对象获取客户提交的汉字代码的时候,会出现乱码:' H q+ Q# l1 `. I% G1 F) \! x% o3 b; Z
解决的办法是:要配置一个filter,也就是一个Servelet的过滤器,代码如下:- ?5 C! n! p9 }6 M; n8 i
import java.io.IOException;
, B+ X! X1 h2 r3 T3 `import javax.servlet.Filter;
: b+ K1 _9 Z# ~: Dimport javax.servlet.FilterChain;( W M. i. Z0 N. F
import javax.servlet.FilterConfig;& p0 Z1 x3 L) h1 f, \, k+ Q1 g
import javax.servlet.ServletException;
, s( \0 r9 u( Q$ bimport javax.servlet.ServletRequest;
, T3 l! ]: z8 w& |9 Mimport javax.servlet.ServletResponse;
( u R7 Y2 y& y" Iimport javax.servlet.UnavailableException;
0 ]7 E5 z& Z h; r) z% B Q; ?3 v
& C2 ?) u8 n- o/**6 G: P: ^, F4 z4 s' b6 O
* Example filter that sets the character encoding to be used in parsing the
5 W0 p6 l \$ d$ r: C# y * incoming request0 G2 Q; f/ }" `4 d- M w
*/
- G! e8 b$ E7 C8 y( Z- w- t6 ^/ c' ypublic class SetCharacterEncodingFilter implements Filter {! t W/ k; U8 j- P+ R. a5 ?" B
4 j) j' D8 H3 d2 |7 E N* V
/**
. Z- @# t1 P4 f4 B: k, I$ ] * Take this filter out of service.
! g2 {; M% `, h8 A1 U; u/ D V */) ~6 h& w$ ^8 m
public void destroy() {) h' D* y" O2 W3 X
}4 I* `& e* }8 w, G! j
/**
7 W- U. m* W* @$ a * Select and set (if specified) the character encoding to be used to
% H) i- p6 D' H& G * interpret request parameters for this request./ N6 a2 I! G8 ?2 q
*/- K( ^, C, C% q6 \ `0 s7 G) ?9 _3 U
public void doFilter(ServletRequest request, ServletResponse response,1 s2 C' w9 o% _7 F& ~& E m% a
FilterChain chain)throws IOException, ServletException {
, P: V& I' F* @) r
9 `# m& ?2 b0 G% m- t& @ request.setCharacterEncoding("GBK"); ?4 q- c, J) V; M
. |5 V+ z$ C+ O* _8 c
// 传递控制到下一个过滤器
3 U: N3 \6 J* X! K& j' V chain.doFilter(request, response);
! U; D! Q" U' V1 p6 S }
& z0 V) W* k& {1 p9 f- Q: _3 [
3 Q* j- S5 _& e3 R) {& |" Z E: {6 L public void init(FilterConfig filterConfig) throws ServletException {
}. d- u$ }9 {$ N3 S6 C; _ }2 Z0 T! Y. i5 ^; I) m; {
}. u' z8 |9 y% q( C; t* b0 V
配置web.xml A0 w) v4 |" S) _( z* q" r
<filter>8 k1 ]) K: j# D
<filter-name>Set Character Encoding</filter-name>
: m. Q3 _ U6 W# O5 B) R3 ?- M& {3 L<filter-class>SetCharacterEncodingFilter</filter-class>' u, n0 X* u( G& }0 \8 b8 P
</filter>. z% _% }% t9 {, Q8 v, K& E
<filter-mapping>
: \/ Z' `5 v! r+ K& b# q<filter-name>Set Character Encoding</filter-name>, Y F. Z" n) J( b, H
<url-pattern>/*</url-pattern>$ X# a) K' h& B. y
</filter-mapping>3 t: o, v! w! p, t/ L
如果你的还是出现这种情况的话你就往下看看是不是你出现了第四中情况,你的Form提交的数据是不是用get提交的,一般来说用post提交的话是没有问题的,如果是的话,你就看看第四中解决的办法。
5 z) d4 G# a; J; ^还有就是对含有汉字字符的信息进行处理,处理的代码是:0 k8 `1 P4 X( f6 V/ Z
package dbJavaBean;/ e4 B7 T9 _" y9 u0 d! t
: R) Y, x5 N( P8 t o6 l: O G
public class CodingConvert/ O6 w1 s/ h% ^) N, \+ i& j) t
{ 8 B: J6 v3 ?" i& I7 w" C
public CodingConvert()" h4 R* }# |) O
{2 N+ v/ q: [( H6 H3 a5 q
/// H# x2 Q2 {4 ^: A* e
}
1 T9 _7 C5 y, ?- m3 ]2 p) Z public String toGb(String uniStr){
$ F/ V% ]7 F- T& V8 E+ {7 ] String gbStr = "";: d/ f# Q1 D$ z }0 _% J- _2 x& c
if(uniStr == null){* s& Z' ]0 h6 E( G& H+ U& F
uniStr = "";
; h& F" I" B/ F# [3 A# z* ~ }
$ d, J- X% V% @; H. F+ `+ T try{
3 V! s2 B% B' l: i byte[] tempByte = uniStr.getBytes("ISO8859_1");' _' e8 h" t2 h- K
gbStr = new String(tempByte,"GB2312"); O6 w8 i' o' T" E7 q, O
}
' W4 _1 b: F( _5 E4 U8 q/ g catch(Exception ex){# }& s* Y& H( T* y: ]& x' z
}
: \5 n/ g, k5 z _8 H1 i' ]; j+ e- z return gbStr;
" e2 `* G# R! q$ h2 f/ i# @/ S0 N }
. E2 B8 Z t; c8 u; J! ]
! w) v, W- m) ~3 t: P public String toUni(String gbStr){
' A$ O& N, @* J0 J String uniStr = "";, P* o' h) S' k) |5 N
if(gbStr == null){9 {% _0 `# y% j$ q! A% P2 F
gbStr = "";
" p1 m& q6 N8 x) e& R% B' i$ Z }. [, y5 J1 h' A+ T
try{
, F2 D0 ]9 X: n- N8 G6 O& T byte[] tempByte = gbStr.getBytes("GB2312");; `9 g! |. x9 Y
uniStr = new String(tempByte,"ISO8859_1");0 ]! w2 A) n7 x
}catch(Exception ex){; M7 S$ |, v- ]: f/ U
}5 s5 N) A! G( u; m8 {2 J
return uniStr;
% A" H, q" m! ?( p* \; x7 u }' Q7 y5 V4 Z0 G, {2 ^3 }# b
}" Y* u+ h; z1 c- S0 F1 W
你也可以在直接的转换,首先你将获取的字符串用ISO-8859-1进行编码,然后将这个编码存放到一个字节数组中,然后将这个数组转化成字符串对象就可以了,例如:
& c* H2 I" L6 x: ?4 VString str=request.getParameter(“girl”);
; J/ S+ m9 M0 v- h+ gByte B[]=str.getBytes(“ISO-8859-1”);
! J: F5 z' q( ]9 _( Z$ j% n; OStr=new String(B);
3 S# `, c! j! E, M# U6 w6 q1 r* J通过上述转换的话,提交的任何信息都能正确的显示。
0 F, c. [8 A# i: Q, J) V) c(三) 在Formget请求在服务端用request. getParameter(“name”)时返回的是乱码;按tomcat的做法设置Filter也没有用或者用request.setCharacterEncoding("GBK");也不管用问题是出在处理参数传递的方法上:如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法进行处理的话前面即使是写了:. k) L& ?) B. s' Z. i; ?6 s3 B
request.setCharacterEncoding("GBK");5 k3 @! l/ }# Q( [. |
response.setContentType("text/html;charset=GBK");1 A+ ?6 q5 w4 T4 ]) ^& @# K3 Q6 d
也是不起作用的,返回的中文还是乱码!!!如果把这个函数改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。, M: b# O* N# G: C" x' e z
同样,在用两个JSP页面处理表单输入之所以能显示中文是因为用的是post方法传递的,改成get方法依旧不行。$ _! A. ~3 A8 E$ B' K( ^) X7 Q
由此可见在servlet中用doGet()方法或是在JSP中用get方法进行处理要注意。这毕竟涉及到要通过浏览器传递参数信息,很有可能引起常用字符集的冲突或是不匹配。2 p1 {6 w$ `5 u& ]
解决的办法是:
: Z( y. D( o2 c8 s6 i+ h7 x* K J1) 打开tomcat的server.xml文件,找到区块,加入如下一行: 7 X8 f: g' q8 d% J( K& e
URIEncoding=”GBK”
* h5 B( V, C2 J2 n# [. {" }完整的应如下: 2 F8 j, X! f' P
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/> / W* D3 j5 a5 Z0 W5 g l
3 }3 V, ?7 |0 c1 M0 O2)重启tomcat,一切OK。: Y6 P) i, O" {* p% K. r
需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的这个文件就可以知道原因了。需要注意的是:这个地方如果你要是用UTF-8的时候在传递的过程中在Tomcat中也是要出现乱码的情况,如果不行的话就换别的字符集。
& O' S& Y. y% f$ m: G8 ^0 o) P2 |/ Q8 w8 u, E# Z& Z0 \- t8 M
(四) JSP页面上有中文,按钮上面也有中文,但是通过服务器查看页面的时候出现乱码:) x( Y' y3 w; ^. S6 \5 d
解决的办法是:首先在JSP文件中不应该直接包含本地化的消息文本,而是应该通过<bean:message>标签从Resource Bundle中获得文本。应该把你的中文文本放到Application.properties文件中,这个文件放在WEB-INF/classes/*下,例如我在页面里有姓名,年龄两个label,我首先就是要建一个Application.properties,里面的内容应该是name=”姓名” age=”年龄”,然后我把这个文件放到WEB-INF/classes/properties/下,接下来根据Application.properties文件,对他进行编码转化,创建一个中文资源文件,假定名字是Application_cn.properties。在JDK中提供了native2ascii命令,他能够实现字符编码的转换。在DOS环境中找到你放置Application.properties的这个文件的目录,在DOS环境中执行一下命令,将生成按GBK编码的中文资源文件Application_cn.properties:native2ascii ?encoding gbk Application.properties Application_cn.properties执行以上命令以后将生成如下内容的Application_cn.properties文件:name=\u59d3\u540d age=\u5e74\u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"/>。到这一步,基本上完成了一大半,接着你就要在JSP页面上写<%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那个label是要写<bean:message key=”name”>,这样的化在页面上出现的时候就会出现中文的姓名,年龄这个也是一样,按钮上汉字的处理也是同样的。
' I! ]0 _! h7 \1 a( {(五) 写入到数据库是乱码:, O; f/ e( d8 Q$ \
解决的方法:要配置一个filter,也就是一个Servelet的过滤器,代码如同第二种时候一样。* J6 k3 B4 K/ X# k% {; z1 k) M5 V
如果你是通过JDBC直接链接数据库的时候,配置的代码如下:jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK,这样保证到数据库中的代码是不是乱码。
: | c2 v$ f8 B8 l' R如果你是通过数据源链接的化你不能按照这样的写法了,首先你就要写在配置文件中,在tomcat 5.0.19中配置数据源的地方是在C:\Tomcat 5.0\conf\Catalina\localhost这个下面,我建立的工程是workshop,放置的目录是webapp下面,workshop.xml的配置文件如下:
' T: f9 h) ~/ X0 C3 j o( ^<!-- insert this Context element into server.xml -->
' w! f0 [/ r4 g1 G- ^! {$ p" ]
$ v8 K) e3 W7 L( n) v<Context path="/workshop" docBase="workshop" debug="0"
' w0 l" [# a! A: Oreloadable="true" >
8 A7 h" {8 N* M2 s" k' K: h9 c7 H9 O' h& F8 t
<Resource name="jdbc/WorkshopDB"$ [0 `+ ^1 @7 I! w1 U; k
auth="Container" [$ x7 {! P$ f2 R) p( o- }$ r
type="javax.sql.DataSource" />
( U0 T! z ^8 Y1 D! [2 j6 }: L; w1 q0 {8 I1 Z
<ResourceParams name="jdbc/WorkshopDB"># F' A8 V9 ~+ ?4 P) a5 I- j8 f
<parameter>
. a4 H: @( z# v. f <name>factory</name>
' Q9 M: ]* E& U/ X% b' x* j' n2 k <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
3 a: [% Z8 @, o! h; U% g4 C </parameter>
/ }" [4 T. m1 S' K* c \7 u <parameter>8 z$ c$ B' j' G8 ` }1 @8 q
<name>maxActive</name>
. p7 r6 n4 s; z2 Z- I' C4 u <value>100</value>
1 g; b4 ?+ g2 u </parameter>7 N5 u5 M- |3 m( ^- D1 E8 i
<parameter>
3 s; m- O7 L6 A% t. q <name>maxIdle</name>
! W9 A' H: `' E! T: ^8 X <value>30</value>
& d# Z* p. I, P6 x& k% e8 c </parameter>
, C% ` Y6 D: b- c, k' \6 h& b$ W+ w" i P5 E5 |
! s, m4 @0 o+ A+ A- l7 Z) P <parameter>6 S' R9 ~; W0 b( W, o! K3 U
<name>maxWait</name>5 M/ I2 g9 Z3 T
<value>10000</value>- K1 P1 X6 X, \% m: q. S
</parameter>* u7 V3 L5 e7 `3 A* ^1 ~
0 X, I3 e- k. s' E% x- a) P( ?
<parameter>! r% ?! C/ I3 K7 j( ~4 g
<name>username</name>3 D" f# c/ R4 b. t# Z' E
<value>root</value>1 I, A) E/ v: |, ~
</parameter>2 R2 z+ r- c3 V$ }2 c: R2 ^
<parameter>( M* F, C5 a1 [: C8 U& S: Y
<name>password</name>
/ N9 e8 j: P {; b0 M: f. Z- B <value></value>
" F( {; F% }5 R9 X$ C </parameter>
5 R! _ W! }8 p% s: g$ N$ \# L5 T+ _: [! m. B2 @
<!-- Class name for mm.mysql JDBC driver -->! g7 S: H$ C! V4 `" J
<parameter>
/ p& |3 m1 p4 z/ m0 u# U <name>driverClassName</name>
. I u" @0 D; z0 d3 C <value>com.mysql.jdbc.Driver</value>" Z/ h1 Y( N: u( c. o
</parameter>9 B5 B5 G3 Y4 r3 _2 D9 L
<parameter>, V& C- _# L, z$ s) J8 c b
<name>url</name>& ]: Y+ x0 }( x
<value><![CDATA[jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&characterEncoding=GBK]]></value>1 Z$ @5 G0 Y0 J
</parameter>8 y5 r: O* V4 r; V
</ResourceParams>3 d% Y6 e O0 S7 z
# e, m1 p! [3 V9 F1 ~1 {</Context>
! E) ?' C# H+ \7 x2 D粗体的地方要特别的注意,和JDBC直接链接的时候是有区别的,如果你是配置正确的化,当你输入中文的时候到数据库中就是中文了,有一点要注意的是你在显示数据的页面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>这行代码的。需要注意的是有的前台的人员在写代码的是后用Dreamver写的,写了一个Form的时候把他改成了一个jsp,这样有一个地方要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他该过来,因为在jsp的提交的过程中紧紧就是POST和GET两种方式,但是这两种方式提交的代码在编码方面还是有很大不同的,这个在后面的地方进行说明。