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

snowfox373 2007-11-24 11:21

解决JSP中使用request乱码问题

JSP显示中文有乱码怎么办,用request得到的用户输入的中文怎么是乱码,把汉字写到数据库怎么是乱码,等等一些关于汉字乱码的问题。其实这个问题很简单,管它汉字不汉字,还是日文,还是其他的什么双字节的语言,我们一律把它当作UTF-8看待。A#ziNV A(J"r3I

l'ce4o6iGEC(c       (一)request中的双字节文字
*K1bS$gT {
fa Q+]8|9q       我们来实现在整个应用程序中使用UTF-8编码工作,之所以选择UTF-8不仅仅之于上述原因,我们知道java的就是基于在UTF-8之上的,所以我们选择UTF-8应该没错
%]$s6a3E sh 首先把我们的.java, .jsp文件都用UTF-8编码来保存,如果以前的没有用UTF-8保存也无所谓,但是建议以后写的都用UTF-8来保存。 Q$m%c&bd$t:}W,S

Gmk k,Z;I}D z       并在.jsp里面写:[code]<%@page contentType="text/html; charset=UTF-8"%>而不是%@page contentType="text/html; charset=UTF-8"%[/code]然后在web.xml添加下面一段:[code]<web-app>
B%s M:`6B2\ ...
d8K0\H4|ya0j_0[r   <filter> gT7e"j0qI
    <filter-name>Set Character Encoding</filter-name> @ d{[Xmqc @
    <filter-class>com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter</filter-class>
(e i/xNl]Fd&o)F     <init-param> 7H A&j)^0q*?S
      <param-name>encoding</param-name> +^&T9F\{!{!A__
      <param-value>UTF-8</param-value>
f$r(TD$U4l.E4S1jQ     </init-param>
b+Ur:_p5S/s?w   </filter> 2}+k:n)q8a? ~
  <filter-mapping> E6} z)J])_z
    <filter-name>Set Character Encoding</filter-name> Hu;`{y a'h%k gq
    <url-pattern>/*</url-pattern>
+\ J$P]{y1~%_s"R
G m}7CP&X o6Q9b   </filter-mapping> Rn)IH^U3X
... 2h%AiP;Cdt|
</web-app>[/code]其中com.redv.projects.eduadmin.util.filters.SetCharacterEncodingFilter的代码如下:[code]package com.redv.projects.eduadmin.util.filters; P7vo&Q'?
import java.io.IOException; )Y:}\1[.g!y,{
import javax.servlet.Filter; -j OK/FInZ1usl
import javax.servlet.FilterChain;
L;L(X"ty+]mn!l import javax.servlet.FilterConfig; :@ W8Pe6|
import javax.servlet.ServletException; #cNU9|&`
import javax.servlet.ServletRequest;
#dyKh-Y0Bt]P import javax.servlet.ServletResponse;
$g B1|6EY_.O import javax.servlet.UnavailableException; v]/@4|Q U
import javax.servlet.http.HttpServletRequest; O1sm s6k.T1@
import javax.servlet.http.HttpServletResponse;
S3~N,f9q2y'{1d
]-?%@T%` { public class SetCharacterEncodingFilter
0a0a9^n|3{wN[ P     implements Filter { C!LZ [c/L\QW5L4g
O k&I&NUn)k&P1U1l8E
  protected String encoding = null;
+C T5@o&J` K*d J:w-@ g   protected FilterConfig filterConfig = null; c1NeQg:ImM E
  protected boolean ignore = true;
$fB/z r9d$b   public void destroy() {
.{&e | y#Z*d"dJ     this.encoding = null; @%hA$a Xj8Z-L T
    this.filterConfig = null;
u;@I B] s   }
#W,D:|2O^'zosR e   public void doFilter(ServletRequest request, ServletResponse response, x(rl S5Na
                       FilterChain chain) throws IOException, ServletException {
'M]j_%^ZR*O"hM     // Conditionally select and set the character encoding to be used
P+g/Ka/FQByD9]     if (ignore || (request.getCharacterEncoding() == null)) { \6o;p3uiz6S i
      String encoding = selectEncoding(request);
$i ]1tU4m,L IV       if (encoding != null) { d b.Z(~9f
        request.setCharacterEncoding(encoding);           //
8] YhH d/f0v4J F 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().
4jdF0|*Rlh?.F       }
8ga i9xH0U     } "@Y4|Rd(I9d
    // Pass control on to the next filter `s [w%RN
    chain.doFilter(request, response); DC0lB"]0Cn
  }
7h'L8W G*Ej+P)zFV   public void init(FilterConfig filterConfig) throws ServletException {
0MT;@jRid5Y     this.filterConfig = filterConfig; w%`1EQ:F#_~
    this.encoding = filterConfig.getInitParameter("encoding"); s]#T.w*tLU
    String value = filterConfig.getInitParameter("ignore");
bZha&C9z"s`w     if (value == null) {
VL%NM*n)m"w       this.ignore = true;
)o{0R/J2k     }
AeB^ w1c#_     else if (value.equalsIgnoreCase("true")) {
?V{6Z4T)j       this.ignore = true;
s e KJur7h     }
Hbzg%e!G?     else if (value.equalsIgnoreCase("yes")) { Y#c U;`0qYE+zC'I+NY
      this.ignore = true; y FdI0[
    } /lj{eX4e5MA-]
    else {
1M KCHp ~U       this.ignore = false;
@mw:Y[+B     } B WO(]$mq
  }
Le W7a/QA{9QU M   protected String selectEncoding(ServletRequest request) {
)kv j O6Y     return (this.encoding); *G.loMbH&bT\
  }
S%FE N(D!["F~[ }[/code]这样,我们的request请求就是以UTT-8编码的,在JSP程序中就可以使用:request.getParameter("myKey")来直接得到UTF-8编码的字符串了,而不需要像这样:new String(request.getParameter("myKey").getBytes("ISO-8859-1"), "GBK")来解决那些乱码了。1^:YfB$l S IC&C
,k u k&t6R D ^^
      (二)数据库处理的双字节文字
!dtuK/v.q 'i&|a'qm
      另外一个,就是写入数据库的问题,我们知道我们在使用mysql的时候可以改用这样的url来处理汉字编码问题:jdbc:mysql://localhost:3306/upas?useUnicode=true&characterEncoding=gb2312,那么对于那些我们无法像mysql这样解决的怎么办呢?难道我们每次都这样写吗:[code]import java.sql.*; $OV.d'q@_LY}._5UsD
Class.forName("org.gjt.mm.mysql.Driver"); x(@#jwH
Connection con = null; ]"K$G,|X(Ie1pf
PreparedStatement pstmt = null;
r Ta\ w ResultSet rs = null; !jT5o} R;{
try {
1A F2r1q)tA){0q`7G   con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", ""); &@\ N1]3[
  pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
av'?+s/uZ&Y4|I   pstmt.setString(1, new String(f1.getBytes("GBK"), "ISO-8859-1"); :e"YVH)? y2g
  pstmt.setString(2, new String(f2.getBytes("GBK"), "ISO-8859-1"); QI:I b|l%W(Onu
  rs = pstmt.executeQuery();
?&K&A u/U _   String f3, f4;
.j"L'c2I&f[   while(rs.next()) {
&?7Xr'uNn9E^.lc     f3 = new String(rs.getString(1).getBytes("ISO-8859-1"), "GBK"); :K F:_zM l O$u
    f4 = new String(rs.getString(2).getBytes("ISO-8859-1"), "GBK"); X$WM@%W.Y\ j?
  } S2g)Yy$L?
} 3biQ&b8{
finally { p!x'j4E9U$O-W
  //close resouces .\*e;z!T|.| kl
  ... j7@~9Rr I p(b
}[/code]其实我们完全可以这样写:[code]import java.sql.*; %c(p;@!sqGK)w
import com.redv.sql.encoding.*;
5R2oucGjuL|2d u#Y Class.forName("org.gjt.mm.mysql.Driver"); H3\p8r:C
Connection con = null; }!^.})wDjx%I
PreparedStatement pstmt = null; \^)\t"GA \
ResultSet rs = null;
^G,aN3z?^ try { RG^{nn
  con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", ""); 6aO(AP^4LWN
  //接管数据库连接实例
a'aFPI|   boolean coding = true; ,Ynq D a5P
  EncodingConnection codingConnection = new EncodingConnection(con, coding, "ISO-8859-1", "GBK"); 7n1Vd+M-hUP*d~
  //获得接管后的数据库连接实例,以后直接使用con已经是经过EncodingConnection重新包装过的实例
T,t7{|'DAnE"kz   con = codingConnection.getConnection(); F+u'e%G l+PY!{
  pstmt = con.prepareStatement("SELECT f3, f4 FROM tbl1 WHERE f1 = ? AND f2 = ?");
1I.v"Lq,t4Ayb Go   pstmt.setString(1, f1);
l!_A0Szkd   pstmt.setString(2, f2);
E'CDc"WS^/VQ   rs = pstmt.executeQuery(); |C`J'oj eo
  String f3, f4; G Pl(JPQ
  while(rs.next()) { 1S'J,T"o{usn
    f3 = rs.getString(1);
5QA#gkE0DmH Y     f4 = rs.getString(2); d.z(S!j6?ct"Wx$}
  } 0r:\;D%AB3C
}
QARq*@.BF_ finally {
;\!{9P)~ oW:o0~"c#Ac   //close resouces
a]#eL_T5k   ...
&h;Z.PWU }[/code]看看,怎么样,我们只需要在获取数据库连接的地方稍微修改一下,甚至我们可以把它当作参数保存在 properties里面,改变coding的布尔值来设定是否使用自动编码转换。常常我们可以使用一个Database类来封装获取数据库连接的那段getConnection,以便于我们可以从 javax.sql.DataSource中获取到数据库连接。这个时候我们仅仅需要修改我们的Database类即可,而不用去搜索所有使用了rs.setString(), rs.getString()的地方去加入我们的编码转换代码了。
页: [1]
查看完整版本: 解决JSP中使用request乱码问题