隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

          Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題

          本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝

              有個(gè)朋友寫(xiě)JSP程序時(shí),在Servlet中取請(qǐng)求參數(shù)時(shí)出現(xiàn)了亂碼,當(dāng)然,這種亂碼問(wèn)題再簡(jiǎn)單不過(guò)了。由于在JSP中使用了GBK作用頁(yè)面的編碼,那么提交的中文信息自然也會(huì)被按著GBK進(jìn)行編碼,為%xx格式的GBK編碼。
              要解決這個(gè)問(wèn)題可以說(shuō)是方法多多。最簡(jiǎn)單的就是使用request.setCharacterEncoding方法設(shè)置編碼格式,如下面的代碼所示:

          request.setCharacterEncoding("GBK");

              在設(shè)置完編碼格式之后,就可以直接通過(guò)request.getParameter方法來(lái)獲得請(qǐng)求參數(shù)中的中文信息了。當(dāng)然,為了方便,還可以在過(guò)濾器中加入上面的語(yǔ)句,這樣所有的Servlet都可以直接使用
          request.getParameter方法來(lái)獲得請(qǐng)求參數(shù)中的中文信息了。 除了這兩種方法,還可以不使用request.setCharacterEncoding("GBK"),而使用下面的語(yǔ)言來(lái)轉(zhuǎn)換編碼:

          String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

              但為了更快解決這個(gè)問(wèn)題,我就直接告訴這位朋友使用了setCharacterEncoding方法來(lái)設(shè)置編碼。但是說(shuō)來(lái)奇怪,還是出現(xiàn)亂碼,沒(méi)有任何解決問(wèn)題的跡象。 最郁悶的事就是使用了自己認(rèn)為100%能解決問(wèn)題的方法,而這種方法卻一點(diǎn)都沒(méi)起作用。
              最后又讓朋友試了最后一種方法,說(shuō)來(lái)奇怪,竟然好使了。當(dāng)然,這也沒(méi)什么可奇怪的,本來(lái)就應(yīng)該好使,但奇就奇在setCharacterEncoding方法并沒(méi)有去掉,也就是說(shuō),同時(shí)使用了下面兩條語(yǔ)句,竟然得到了正常的中文請(qǐng)求參數(shù)值:

          request.setCharacterEncoding("GBK");
          String name 
          = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");
          System.out.println(name);  
          //  正常輸出中文請(qǐng)求參數(shù)

              按著常理來(lái)說(shuō),這是不可能的,既然使用了setCharacterEncoding方法設(shè)置成了GBK,再使用
          new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK")來(lái)轉(zhuǎn)換,得到的應(yīng)該是?????,不可能是正常的中文,只有將setCharacterEncoding方法去了,以ISO-8859-1格式保存的字符串才可以用ISO-8859-1格式還原,再用GBK重新保存成Java字符串(這一步實(shí)際上就是GBK轉(zhuǎn)Unicode)。

              但經(jīng)過(guò)仔細(xì)思考后,決定看下JSP代碼是如何寫(xiě)的。不看不知道,一看嚇一跳,原來(lái)<form>在提交時(shí)使用的是GET,而未用POST,這當(dāng)然沒(méi)什么了不起的,用什么都可以,但對(duì)編碼就有問(wèn)題了。自從Tomcat5.x開(kāi)始,GET和POST方法提交的信息,Tomcat采用了不同的方式來(lái)處理編碼,對(duì)于POST請(qǐng)求,Tomcat會(huì)仍然使用request.setCharacterEncoding方法所設(shè)置的編碼來(lái)處理,如果未設(shè)置,則使用默認(rèn)的iso-8859-1編碼。而GET請(qǐng)求則不同,Tomcat對(duì)于GET請(qǐng)求并不會(huì)考慮使用
          request.setCharacterEncoding方法設(shè)置的編碼,而會(huì)永遠(yuǎn)使用iso-8859-1編碼,而這位朋友使用的正好是GET請(qǐng)求,因此,tomcat將會(huì)使用iso-8859-1將提交的字節(jié)轉(zhuǎn)換成字符串。

          解決的方法有兩個(gè):
          1.  將GET請(qǐng)求改成POST請(qǐng)求,然后就可以使用
          request.setCharacterEncoding方法設(shè)置編碼,并使用request.getParameter方法直接獲得中文請(qǐng)求參數(shù)了。
          2.  不用改GET請(qǐng)求,在Servlet中使用如下的代碼來(lái)得到中文請(qǐng)求參數(shù)。

          String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

              綜上所述,如果使用了GET請(qǐng)求,則setCharacterEncoding方法不起作用,只能使用上面的代碼來(lái)解決,而使用POST請(qǐng)求,盡管
          setCharacterEncoding方法起作用,但使用上面的代碼仍然好使(在這時(shí)不能使用setCharacterEncoding方法將編碼格式設(shè)置成非iso-8859-1格式)。因此,如果想讓Servlet可以同時(shí)處理GET和POST請(qǐng)求中的中文信息,除了判斷這兩種方法外,還可以使用上面的代碼來(lái)同時(shí)處理這兩種請(qǐng)求的中文信息。

              筆者建議使用如下的代碼來(lái)獲得中文請(qǐng)求參數(shù):

          String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");

              因?yàn)樯厦娴拇a是利用了Java的編碼能力,對(duì)于所有的Web服務(wù)器都會(huì)有效,而setCharacterEncoding方法是通過(guò)Web服務(wù)器支持的,并不是所有的Web服務(wù)器都會(huì)對(duì)該方法有很好的支持。





          Android開(kāi)發(fā)完全講義(第2版)(本書(shū)版權(quán)已輸出到臺(tái)灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2008-09-05 15:48 銀河使者 閱讀(3066) 評(píng)論(8)  編輯  收藏 所屬分類: javaweb 原創(chuàng)

          評(píng)論

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   


          我還真以為你發(fā)現(xiàn)了什么。
          2008-09-05 19:44 | 隨便

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          只是解釋一下為什么最好用String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GBK");,哈哈。
          2008-09-05 20:03 | 銀河使者

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          tomcat就是有這樣很變態(tài)的問(wèn)題.
          新人學(xué)習(xí)中....
          2008-09-12 00:19 | 樓上兩位很垃圾

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          謝謝。確實(shí)很大幫助。其他網(wǎng)頁(yè)上通常說(shuō)在server.xml中設(shè)置URIEncoding就可以,但事實(shí)上不起作用。采用筆者使用的方法成功了。 我使用的是Tomcat 6。
          2008-09-25 20:46 | 專吃飯右手

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          一直搞不明白為什么request.setCharacterEncoding("GBK")不起作用,看了這篇文章,茅塞頓開(kāi)。
          2008-10-05 10:14 | 文濤

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          好!
          2008-10-24 16:05 | lyshyhaungli

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          j2ee的API里說(shuō)的很清楚
          setCharacterEncoding
          public void setCharacterEncoding(java.lang.String env)
          throws java.io.UnsupportedEncodingExceptionOverrides 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().
          有什么疑問(wèn)請(qǐng)參考http://rubyeye.javaeye.com/blog/266705

          # re: Tomcat在處理GET和POST請(qǐng)求時(shí)產(chǎn)生的亂碼問(wèn)題  回復(fù)  更多評(píng)論   

          真是太感謝這篇樓主了,這篇帖子很棒!
          2009-05-31 19:12 | 茅塞頓開(kāi)
          主站蜘蛛池模板: 桃源县| 东兰县| 雷山县| 巴林右旗| 山东省| 若尔盖县| 阿勒泰市| 武宁县| 嵩明县| 云阳县| 巴林左旗| 诸城市| 湾仔区| 临桂县| 临武县| 镇原县| 成安县| 万安县| 浮梁县| 洞头县| 漳浦县| 四子王旗| 扎兰屯市| 开鲁县| 张家口市| 阜康市| 怀化市| 建德市| 阿克苏市| 英德市| 庆云县| 石家庄市| 九寨沟县| 招远市| 喀什市| 上饶县| 易门县| 遵化市| 龙州县| 乡城县| 东辽县|