查看完整版本: 解决JSP中使用request乱码问题

snowfox373 2007-11-24 11:21

解决JSP中使用request乱码问题

JSP显示中文有乱码怎么办,用request得到的用户输入的中文怎么是乱码,把汉字写到数据库怎么是乱码,等等一些关于汉字乱码的问题。其实这个问题很简单,管它汉字不汉字,还是日文,还是其他的什么双字节的语言,我们一律把它当作UTF-8看待。O,r0`)f V(q+L
t5g T&]tg
      (一)request中的双字节文字+kD@%n7N4MP
C Ha"Mu hR1Qi
      我们来实现在整个应用程序中使用UTF-8编码工作,之所以选择UTF-8不仅仅之于上述原因,我们知道java的就是基于在UTF-8之上的,所以我们选择UTF-8应该没错
e3f.T!_ qs g9Z 首先把我们的.java, .jsp文件都用UTF-8编码来保存,如果以前的没有用UTF-8保存也无所谓,但是建议以后写的都用UTF-8来保存。 N*] ~!p1p,j
?`:IB2etUD+d3V
      并在.jsp里面写:[code]<%@page contentType="text/html; charset=UTF-8"%>而不是%@page contentType="text/html; charset=UTF-8"%[/code]然后在web.xml添加下面一段:[code]<web-app> \qv!O5S)X
... 9t,a5a*fk.GQI)JV
  <filter> GIBkV2[7d
    <filter-name>Set Character Encoding</filter-name>
Y Z|Jtb,m/x;t)Y6Av     <filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class> x_.z F;K q0g#\;R
    <init-param>
"Y#i(i ]i/hd       <param-name>encoding</param-name>
rU wL2Tt       <param-value>UTF-8</param-value>
b1m3vTmt7b     </init-param>
D:LM4LRIh qtlu   </filter>
S| S0X:@_   <filter-mapping> 4_U3t EN6h6A
    <filter-name>Set Character Encoding</filter-name>
;O/n\SaW0f     <url-pattern>/*</url-pattern> @ C Ugu6r
X5w'y1L/p%@
  </filter-mapping>
(CO|4Q.`_su ...
7ZC)I]\F*l| </web-app>[/code]其中com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter的代码如下:[code]package com.redv.projects.eduadmin.util.filters; |B,b4T yaE
import java.io.IOException; ay;G v _ISp(p
import javax.servlet.Filter;
0[ `+LgLc$k import javax.servlet.FilterChain;
DU%VA7@2B import javax.servlet.FilterConfig; _ dK*IF W^
import javax.servlet.ServletException;
Ma:WPY| import javax.servlet.ServletRequest; m$M#S$zk GR[
import javax.servlet.ServletResponse; #rWi2h3{8~(m
import javax.servlet.UnavailableException;
/GqO!LK-h import javax.servlet.http.HttpServletRequest; ~O$gl$Q6?7j
import javax.servlet.http.HttpServletResponse; ,B9i^ @G.R9e Lc9U"vz(}

4z*QQWQ dvd public class SetCharacterEncodingFilter JO1LP S N
    implements Filter {
T-P)g8e0l:Erl%P be+F2x$MZ*T/J
  protected String encoding = null; PB8p*[J
  protected FilterConfig filterConfig = null; -c^%t[!tq#L[
  protected boolean ignore = true;
}~S5Evz*K a   public void destroy() {
W Y,l)m$yz|     this.encoding = null; P(ySJ*A:sB3I
    this.filterConfig = null; )qp;n(II(LZ4_
  } U*jQ PA0f:^
  public void doFilter(ServletRequest request, ServletResponse response,
!J5}9YD.c0X+R                        FilterChain chain) throws IOException, ServletException { 8l;\l1q4GW@9o^
    // Conditionally select and set the character encoding to be used 1F J`A4i c-{O
    if (ignore || (request.getCharacterEncoding() == null)) {
.^$qPW8U       String encoding = selectEncoding(request); 0E ri;J k8z7k
      if (encoding != null) { ^_C2c-GI(lLBA
        request.setCharacterEncoding(encoding);           //1`&L+lgglS
Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader(). oQNx/T U9Qi2f)cV
      } ~1K-pSO9D
    }
t8x~/Dx*q M     // Pass control on to the next filter
L:tk&d+i     chain.doFilter(request, response);
fc)_v'uu   } 7kZ8It'}X
  public void init(FilterConfig filterConfig) throws ServletException { (\;o'g U$L
    this.filterConfig = filterConfig;
3E'Pl;cGc     this.encoding = filterConfig.getInitParameter("encoding"); druk#fvJf
    String value = filterConfig.getInitParameter("ignore");
%qQ1k:DW(N8f\Pi     if (value == null) { X?8zM-n m5r
      this.ignore = true;
U3_N#s/d,F V     }
sIE,V1j     else if (value.equalsIgnoreCase("true")) { X p2`6Mf$o/Bg)tc
      this.ignore = true;
:s0Owf!F9K wlA     }
Jl)L0URO`L _     else if (value.equalsIgnoreCase("yes")) { ko5T{i6`y)?
      this.ignore = true;
a{H h NL)T     }
o _:@+Yfm(d fX(V`     else {
5i"_'KV0F8q       this.ignore = false;
-x7f6HI#R*R _     }
1r*rB)Vr:d   }
2ff CI)~(TxqS.l]   protected String selectEncoding(ServletRequest request) {
Qml$u#NdH {     return (this.encoding);
&w&J L3X1Fu#R   } |+Uwl:L-pdB
}[/code]这样,我们的request请求就是以UTT-8编码的,在JSP程序中就可以使用:request.getParameter("myKey")来直接得到UTF-8编码的字符串了,而不需要像这样:new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK")来解决那些乱码了。4CG7jT/T1tX?(O

gU+j-FB       (二)数据库处理的双字节文字
i)`f#m8m
EC5FK)B       另外一个,就是写入数据库的问题,我们知道我们在使用mysql的时候可以改用这样的url来处理汉字编码问题:jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,那么对于那些我们无法像mysql这样解决的怎么办呢?难道我们每次都这样写吗:[code]import java.sql.*; Z6oZ @"F.Wr:D:v t
Class.forName("org.gjt.mm.mysql.Driver");
[F~ ^8Y$xa Connection con = null;
4p}6n/Cp*jKC+clf+m PreparedStatement pstmt = null;
$_X#?4MN%K o ResultSet rs = null; ,i ?cR"LP;D
try {
x Z*iqvD'Y's   con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", ""); :z1f^YPi0X?
  pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
-wLp3kX+[5[2`   pstmt.setString(1, new String(f1.getBytes("GBK"), "ISO-8859-1"); h8n\kg
  pstmt.setString(2, new String(f2.getBytes("GBK"), "ISO-8859-1");
c{!UQ-A   rs = pstmt.executeQuery();
j#S"ir6A9s8I   String f3, f4;
%V^o[+P}3o   while(rs.next()) { YA Alj%CO
    f3 = new String(rs.getString(1).getBytes("ISO-8859-1"), "GBK"); 3ObH A)h
    f4 = new String(rs.getString(2).getBytes("ISO-8859-1"), "GBK");
/MX#OF9t,sf8T#U#W%F   }
D sf^i bY,~U }
SO'kkI9_ a(R!P A finally {
dg0P]1g4fL/w   //close resouces R9b.m|%gL9HL
  ... q*a(C;z#K)Z
}[/code]其实我们完全可以这样写:[code]import java.sql.*;
.K st }9? import com.redv.sql.encoding.*; R7Hb!iX9[(B$V0nL
Class.forName("org.gjt.mm.mysql.Driver"); p/\lapN O C
Connection con = null; n Ls$T,|U'}A
PreparedStatement pstmt = null; /H8TN!Hk/F
ResultSet rs = null; xzG+IO,ab @
try {
I rU5~N|8Iq{   con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "");
mOa7niRXg2w4n   //接管数据库连接实例
F-C3y$jc Bi   boolean coding = true;
L {*W S;MsT0f7I|az6E   EncodingConnection codingConnection = new EncodingConnection(con, coding, "ISO-8859-1", "GBK"); S@4Kp*\~
  //获得接管后的数据库连接实例,以后直接使用con已经是经过EncodingConnection重新包装过的实例 U$?3Q+F8?#Z!U"N%l
  con = codingConnection.getConnection(); *_%R9[|%Js_#Eb I
  pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?"); ] i[BXz
  pstmt.setString(1, f1);
z ~ jgO"JO1J   pstmt.setString(2, f2); *i,`YPK n_4bN^
  rs = pstmt.executeQuery(); 8A sA&^M,k4]1yQo
  String f3, f4; 6ep/k[r"jMB]
  while(rs.next()) { r.dm5@\+{'pu+[
    f3 = rs.getString(1); t f'O2_-RJ.U/EZ,yS
    f4 = rs.getString(2);
+|2\^v1S'~{}U0C   } D)vnyW5B-F,M
} 6C*v1G!f @.O
finally {
4if G%LhqT   //close resouces dqk+lK.e`
  ...
n {W7pab(LM,X!G[ }[/code]看看,怎么样,我们只需要在获取数据库连接的地方稍微修改一下,甚至我们可以把它当作参数保存在 properties里面,改变coding的布尔值来设定是否使用自动编码转换。常常我们可以使用一个Database类来封装获取数据库连接的那段getConnection,以便于我们可以从 javax.sql.DataSource中获取到数据库连接。这个时候我们仅仅需要修改我们的Database类即可,而不用去搜索所有使用了rs.setString(), rs.getString()的地方去加入我们的编码转换代码了。
页: [1]
查看完整版本: 解决JSP中使用request乱码问题
查看完整版本: 解决JSP中使用request乱码问题