7 ^$ [1 q% \: C( m" f( T
我们传递了两个参数名称为:username的字段,我们在浏览器中输入:http://localhost:8080/ServletDemo/demo.jsp,然后打印结果: 1 p v8 x/ _. P; b: b8 I wgetParameterValues方法 1 b. e9 r0 y9 W2 _--------------------- / t# Y2 w# z# x5 i参数名称:username 8 A, Z. G% X+ X! `; M) f' @/ Oaaa, 7 w y9 C( C* l/ X2 S6 Obbb, F7 O l" O1 Z4 Z0 ] / r) ^4 ?, o \. D9 A2 N' k7 K% z0 g" w
% @$ @! d' s8 _/ q/ q1 v
: Q) q4 }0 E- O7 ]
getParameterMap方法 3 S+ I o, }2 s: `. Q------------------% ~5 B# o' J% ^$ P) I
参数名:username $ ^8 k, i: s8 B; r7 _aaa,bbb,$ J6 w+ l( c; N9 U
参数名:password& x- S& p9 J! }6 A {8 K6 s
123, ; {3 k; ~9 i8 y* O$ A1 h3 a8 h1 d; ]1 r3 ]& Z6 W: {/ G) e1 {
3 x! u( R- g2 S! y. f9 E1 H
H. T2 ~6 k- c' Z. O3 X3 U4 C% T/ @. E! T
getParameterNames()方法 ; H& l) U) Z$ z----------------------5 j& s7 x* z( s# s$ \
参数名:username , o0 P4 m D- w参数值:aaa9 B B4 S' U+ _( Z: u
参数名:password! O8 V \. m+ Q1 G2 c
参数值:123* E6 Q" \. l# s T& r
$ @6 y6 l d- \
, T4 A* i5 L: ]6 m下面我们再来看一下request的乱码问题:# X. T ~) W% _. a4 K) a
我们还是直接使用demo.jsp中的方式传递参数,当我们在页面文本框中输入"中国"4 g* t3 A: W' q, o
在控制台中打印获取到的username的值,显示的是??,这个是因为Request域中的采用的是ISO8859-1码表的,而我们的demo.jsp使用的是utf-8编码的,所以当我们点击提交的时候,浏览器会将"中国"使用utf-8码表编码,然后web容器创建一对request/response容器对象,数据传入到request容器中,因为request容器使用的是iso8859-1编码的,所以当我们在Servlet中从request容器中读取数据,使用的是iso8859-1进行解码的,所以会出现乱码了,所以我们只需要将request的容器码表设置成和我们页面显示的码表一样就可以了。这样我们在getParameter的时候得到正确的解码(utf-8)数据: U9 ^$ Y: C5 W8 X% a2 M
request.setCharacterEncoding("utf-8");: K2 [% r& n# b
String name = request.getParameter("username");; S/ B/ u% |* i# s, {- m
System.out.println("username:"+name);
复制代码
) m! ]$ u$ ~" V" X$ G$ z
这时候就可以了,就能够正常显示了。 , n8 F7 Q, f1 j. E9 _4 G' z但是问题还没有结束,以上说到的乱码问题是在使用post方式传递的数据,下面我们在来看一下使用get方式传递数据的乱码问题, 1 _3 T. V# P# R7 b. t3 W昨天突然发现request.setCharacterEncoding("UTF-8")这句代码失效,前后台编码统一都是UTF-8,但通过request.getParameter("name")接收到的表单数据依然乱码,后来发现原因是表单的提交方式没有设置,也就是采用了默认的GET方式提交。 7 `! Y& @3 B; t8 ^/ R
那为什么GET方式会出现问题?难道request.setCharacterEncoding("UTF-8")这句代码只对POST方式提交数据才有效? : I! C h" f1 {1 {- U& U做了一些测试之后总结出了一点规律: 7 S$ ^6 v7 i6 _
1、web浏览器对页面上通过GET方式提交的数据会进行URL编码,采用的编码方式通常由html页面上 , G& l1 L- } D. m( ^
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> ) p$ r; X7 T9 A3 ?" @
这个标签内的charset所指定的编码方式决定(前提是:没有自定义浏览器发送数据的编码设置)。比如现在charset="UTF-8",那么当采用get方式提交表单的时候,web浏览器默认会采用UTF-8的编码方式对数据进行编码。, o5 [( V; b9 e+ M J* j5 L0 q4 P
所以,当请求的URL如下时: . ]9 T7 ?3 [% u' l0 c
http://localhost:8080/test/TestServlet?name=中国 2 L- i; T- G/ K7 {9 g; Z
其实真实内容是这样: 7 Z6 ^9 j$ q- }
http://localhost:8080/test/TestServlet?name=%E4%B8%AD%E5%9B%BD " |8 b0 A) d0 E" \ Y: [
其中%E4%B8%AD%E5%9B%BD是对‘中国’二字采用了UTF-8的URL编码之后产生的字符串。 . ?9 N) R' Y$ s5 m! f2、所以,当数据被发送到Web服务器上的时候(测试使用tomcat6),服务器要做的一件事就是解码%E4%B8%AD%E5%9B%BD这个字符串。那么如何解码这个字符串? 2 w7 K( ?5 q: I$ m9 b) m( P
3、在JDK的java.net包下面有一个类叫做URLDecoder,该类即可对URL编码之后的字符串进行解码,如:
URLDecoder.decode("%E4%B8%AD%E5%9B%BD","UTF-8");
复制代码
; O& n; b7 M& h# J. P+ }
5 ^& s, U2 R4 ~- J' M返回解码之后的字符串,第二个参数是指采用何种字符集解码"%E4%B8%AD%E5%9B%BD"这个字符串。打印以上代码成功显示“中国”二字,说明解码正确! , T- `3 [, @" H, @# F- T
4、前面已经说过了:web服务器会自行解码%E4%B8%AD%E5%9B%BD这个字符串,但是我们通过request.getParameter("name")得到的却是乱码,所以问题一定出在web服务器在解码E4%B8%AD%E5%9B%BD这个字符串的时候采用的字符集不对。 * ~/ I: k' g2 Q7 p _$ S3 g- n
5、经过测试发现,web服务器(只测试了tomcat6)对GET方式的数据提交采用的解码字符集是"ISO-8859-1",所以web服务器其实是这样解码的: 2 w {7 ?( `$ m3 H* OURLDecoder.decode("%E4%B8%AD%E5%9B%BD","ISO-8859-1"); , i3 l9 f+ \6 ^+ j: Y因此:明显服务器的解码方式是不对的,因为编码采用的是UTF-8,而解码却用的ISO-8859-1。 2 A) o) z: Q; v7 f4 T" x6、所以,request.getParameter("name")返回的是用ISO-8859-1解码的字符串,那么必然是乱码了! * @/ ~" L6 T' L, M" Z+ U" D
2 v$ [& \6 C. J5 L- b
那么如何获得正确编码的字符串?可以采用以下的方式: 3 Y6 d) l. \: ?- P- F$ u8 A; n
String a = new String(request.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
复制代码
3 `/ ?' K6 w% p9 W; U- U2 h : }5 j5 O {* B G总结:因为GET方式提交数据会被浏览器进行URL编码,而tomcat服务器会采用了错误的解码方式进行解码,所以得的是乱码。而POST方式提交的数据不会被浏览器进行URL编码,所以服务器直接按照request.setCharacterEncoding("UTF-8") 9 K& G! E7 [/ g4 x: p5 ]/ A* h3 ?
所指定的编码方式解析字符串,因此在POST方式下request.setCharacterEncoding("UTF-8")是好用的! 9 x* ` l3 Q. L5 q这里的解决方式有两种, " B$ H* F+ @$ O ~" G" n6 h' ?
一种:是通过String类的getBytes方法进行编码转换,具体java代码是:, O& X0 o& e( {2 _. N! R! A" s
new String(request.getParameter(“name”).getBytes(“iso-8859-1”),“客户端编码方式”)
复制代码
6 q* K5 G O) Q' p' j! Y' U/ m2 {
这里的客户端编码方式就是页面的编码,比如demo.jsp中使用的是utf-8' ~$ q3 ]3 X% `: ]
( L; P1 I3 Q, v3 E: [; W
0 a( x+ {3 i$ R
5 a6 l- b! a4 |/ m- k' Y第二种:在服务器server.xml代码中改配置信息:
0 W" m0 Z1 k- O, G/ H" q
这样我们就修改了Tomcat中的编码和解码字符集了。当tomcat获取客户机使用get方式带来的数据使用URL解码的字符集8 T& D& U1 x. k4 t y3 }) ^+ V# C
当然我们之后修改server.xml之后需要重启服务器的,所以第二种方式是不赞同使用的。 + i v0 E" ]/ a2 H上面我们就讲述了如何解决request的乱码问题, ?1 e: S" n% _0 B
; d+ w* t+ ? K' Y+ O ~ ; H. Y; h7 u: j1 N1 K; L( A下面我们再来看一下请求转发的问题:# C' h' s ^& m$ D' s& F
对于重定向和转发我们这里就不做太多的介绍了,之前不知道说了好多遍了,我们之前说过ServeltContext也是可以得到一个转发对象RequestDispatch的,其实Request也是可以得到一个RequestDispatch对象的,我们还是来做个例子,通过一个servlet转发到另一个servlet:, P- F4 C t7 D8 d/ O2 A
. X9 J6 t% ]" h- K4 t 7 G$ M6 j* V; y" G( b. t. H: s0 P1 ]) [# ~
Servlet1代码:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { ; T/ k( H2 \! v3 G2 V" x7 Y
//在request域中存入一个属性值,然后转发到Servlet2中进行读取, E3 n1 ]( L9 K: D( l& L# f