知识大全 如何解决JSP参数传递乱码

Posted

篇首语:多见者博,多闻者智,拒谏者塞,专己者孤。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 如何解决JSP参数传递乱码相关的知识,希望对你有一定的参考价值。

如何解决JSP参数传递乱码  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  计算机生于美国 英语是他的母语 而英语以外的其它语言对他来说都是外语 他跟我们一样 不管外语掌握到什么程度 也不会像母语那样使用得那么好 时常也会出一些“拼写错误”问题

  乱码的出现根本原因在于编码和解码使用了不同的编码方案 比如用GBK编码的文件 用UTF 去解码结果肯定都是火星文 所以要解决这个问题 中心思想就在于使用统一的编码方案

  jsp页面间的参数传递有以下几种方式 表单(form)的提交 直接使用URL后接参数的形式(超级链接) 如果两个jsp页面在两个不同的窗口中 并且这两个窗口是父子的关系 子窗口中的jsp也可以使用javascript和DOM(window opener XXX value)来取得父窗口中的jsp的输入元素的值 下面就前两种方式中出现的乱码问题做一下剖析

   表单(form)的提交实现参数页面间的传递

  在介绍表单传递参数的内容之前 先来了解一些预备知识 表单的提交方式和请求报文中对汉字的处理

  表单的提交方式

  通常使用的表单的提交方式主要是 post和get两种 两者的区别在于 post方式是把数据内容放在请求的数据正文部分 没有长度的限制 get方式则是把数据内容直接跟在请求的头部的URL后面 有长度的限制 下面是同一个页面两种方式的请求报许文

  Requesttest jsp代码

  

  1. <%@ page language="java" contentType="text/; charset=UTF "   
  2.     pageEncoding="UTF "%>    
  3. <!DOCTYPE  PUBLIC " //W C//DTD HTML   Transitional//EN" "
  4. <>    
  5. <head>    
  6. <meta  equiv="Content Type" content="text/; charset=UTF ">    
  7. <title>Insert title here</title>    
  8. </head>    
  9. <body>    
  10. <%  post方式提交表单  %>    
  11. <form action="
  12.     UserName:<input type="text" name="username"/>    
  13.     Password:<input type="password" name="password"/>    
  14.     <input type="submit" value="Submit">    
  15. </form>    
  16. </body>    
  17. </>   

  

  1. <%@ page language="java" contentType="text/; charset=UTF " pageEncoding="UTF "%> <!D
  2. OCTYPE  PUBLIC " //W C//DTD HTML   Transitional//EN" "
  3. itle>Insert title here</title> </head> <body> <%  post方式提交表单  %> <form action=":<input type="text" nam
  4. e="username"/> Password:<input type="password" name="password"/> <input type="submit" va
  5. lue="Submit"> </form> </body> </>  

  在上面的请求页面的username输入框里输入的是“世界杯”三个汉字 password输入框中输入" "后按下Submit按钮提交请求 截获到的请求报文如下

  Post方式的请求报文代码

  

  1. POST /EncodingTest/requestresult jsp HTTP/    
  2. Accept: image/gif  image/jpeg  image/pjpeg  image/pjpeg  application/x shockwave flash  applicati
  3. on/vnd ms excel  application/vnd ms powerpoint  application/msword  */*    
  4. Referer: 
  5. Accept Language: zh cn    
  6. User Agent: Mozilla/  (patible; MSIE  ; Windows NT  ; Trident/ ; CIBA; aff kingsoft ci
  7. ba;  NET CLR  )    
  8. Content Type: application/x form urlencoded    
  9. Accept Encoding: gzip  deflate    
  10. Host: localhost:    
  11. Content Length:     
  12. Connection: Keep Alive    
  13. Cache Control: no cache    
  14.    
  15. username=%E %B % %E % % C%E % D%AF&password=    
  16. POST /EncodingTest/requestresult jsp HTTP/  Accept: image/gif  image/jpeg  image/pjpeg  image/pjp
  17. eg  application/x shockwave flash  application/vnd ms excel  application/vnd ms powerpoint  applicati
  18. on/msword  */* Referer: : zh cn Us
  19. er Agent: Mozilla/  (patible; MSIE  ; Windows NT  ; Trident/ ; CIBA; aff kingsoft ciba;  N
  20. ET CLR  ) Content Type: application/x form urlencoded Accept Encoding: gzip  deflate H
  21. ost: localhost:  Content Length:   Connection: Keep Alive Cache Control: no cache username=%E
  22. %B % %E % % C%E % D%AF&password=   

  以上报文内容 可以看出post方式的请求报文是有专门的数据部的

  下面的同一请求页面的get提交方式的请求报文

  Get方式的请求报文代码

  

  1. GET /EncodingTest/requestresult jsp?username=%E %B % %E % % C%E % D%AF&password=  H
  2. TTP/    
  3. Accept: image/gif  image/jpeg  image/pjpeg  image/pjpeg  application/x shockwave flash  applica
  4. tion/vnd ms excel  application/vnd ms powerpoint  application/msword  */*    
  5. Referer: 
  6. Accept Language: zh cn    
  7. User Agent: Mozilla/  (patible; MSIE  ; Windows NT  ; Trident/ ; CIBA; aff kingsoft cib
  8. a;  NET CLR  )    
  9. Accept Encoding: gzip  deflate    
  10. Host: localhost:    
  11. Connection: Keep Alive   
  12. GET /EncodingTest/requestresult jsp?username=%E %B % %E % % C%E % D%AF&passwo
  13. rd=  HTTP/  Accept: image/gif  image/jpeg  image/pjpeg  image/pjpeg  application/x shockw
  14. ave flash  application/vnd ms excel  application/vnd ms powerpoint  application/msword  */* Refer
  15. er: : zh cn User Agent: Mozi
  16. lla/  (patible; MSIE  ; Windows NT  ; Trident/ ; CIBA; aff kingsoft ciba;  NET CLR 
  17. ) Accept Encoding: gzip  deflate Host: localhost:  Connection: Keep Alive  

  以上报文内容 可以看出get方式的请求报文没有专门的数据部 数据是直接跟在url的后面

  请求报文中对汉字的处理

  从上面两种报文可以看出页面上输入的“世界杯”三个汉字被替换成了"%E %B % %E % % C%E % D%AF”这样一个字符串 然后发给服务器的 看到这 可能会有两个问题 问题一 这个字符串是什么?问题二 为什么要做这样的替换?

  这个字符串是“世界杯”这三个汉字对应的"UTF ”编码"E B E CE DAF"在每个字节前追加一个"%"后形成的 至于为什么要做这样的转化 我的理解是 因为请求报文会以"ISO "的编码方式编码后 通过网络流的方式传送到服务器端 "ISO "仅支持数字 英文字母和一些特殊字符 所以像汉字等这样的字符"ISO "是不认识的 所以就必须先给这些"ISO "不支持的字符做个“整形”手术 这样才能正确的将页面上的信息传送到服务器端

  这时可能又会有另外一个问题 上面的例子中为什么会选用"UTF "编码 其它的编码方案可以吗?答案是可以的 在jsp页面代码的头部有这样一段代码"<%@ page language="java" contentType="text/; charset=UTF " pageEncoding="UTF "%>"其中charset的值就是浏览器在提交请求报文前 对请求报文做“整形”手术时用的字符集 同是也是浏览器解释服务器的响应页面时的字符集

  在了解了以上内容后 开始剖析表单方式传递参数的乱码问题

  以上例为例 点击"Submit"按钮后 浏览器将做完“整形”手术后的请求报文发送给WEB服务器上的Servlet容器 容器在收到这个请求报文后 会解析这个请求报文并用这个报文的信息生成一个HttpServletRequest对象 然后将这个HttpServletRequest对象传给这个页面所要请求的jsp或Servlet(上例中为"requestresult jsp") 在这个被请求的jsp或Servlet(上例中为"requestresult jsp")中 使用HttpServletRequest对象的getParameter("")方法来取得上一页面传来的参数 默认情况下 这一方法使用的是"ISO "来解码 所以对于英文或数字的参数值自然能正确取得 但对于汉字这样的字符是解不出来的 因为那几个汉字曾经做过“整形”手术 已经认不出来了 要想再把它们认出来 那就得要把手术的主刀医生找到 然后再做一次“还原”手术 下面提供的几个方案 可用于不同的情况

  方案一代码

  

  1. <%String str = new String(request getParameter("username") getBytes("ISO ") "utf "); %>    
  2. Username:<%=str %>   
  3. <%String str = new String(request getParameter("username") getBytes("ISO ") "utf "); %> Usern
  4. ame:<%=str %>  

  既然request getParameter("username")默认情况下返回的字符串是用"ISO "解出来的 那就先把这个不可辨认的字符串再用"ISO "来打散 也就是 request getParameter("username") getBytes("ISO ") 最后再用跟你的页面的charset一致的字符集来重组这个字符串 new String(request getParameter("username") getBytes("ISO ") "utf ") 这样就能见到它的庐山真面目了

  方案一是一种比较万能的方法 不管是post还是get都适用 但可以看出它的缺点是 对于每个可能出现汉字的参数都要显示的做这么一段处理 一个两个还行 要是很多的话 那就应该考虑一下是不是可以选用下一种方案

  方案二代码

  

  1. <%request setCharacterEncoding("UTF "); %>   
  2. <%request setCharacterEncoding("UTF "); %>  

  方案二是在页面的最开始或者是在该页面中使用的第一个request getParameter("")方法之前加上上述一段代码 它的作用是用作为参数传入的编码集去覆蓋request对象中的默认的"ISO "编码集 这样request getParameter("")方法就会用新的编码集去解码 因为"UTF "支持中文 所以作为参数传过来的“世界杯”三个汉字就能正确的接收到了 但关于request setCharacterEncoding("")方法 API文档中有如下的说明

   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() Otherwise it has no effectb

  所以方案二只对post方式提交的请求有效 因为参数都在request的body区 而对get方式提交的请求则是无效的 这时你会发现同样的做法但显示的还是乱码 所以你的请求要是是以get方式提交的话 那你还是乖乖的选用方案一吧!

  从上面的叙述可以知道 方案二需要在每个页面的前头加上<%request setCharacterEncoding("UTF "); %>这段代码 这样做是不是也挺累的 所以我们想到了使用过滤器来帮助我们做这件事儿 那就清爽 简单多了

  Encodingfilter代码

  

  1. public class EncodingFilter implements Filter     
  2.         
  3.     private String charset;    
  4.     @Override    
  5.     public void destroy()     
  6.         // TODO Auto generated method stub    
  7.         
  8.    
  9.     @Override    
  10.     public void doFilter(ServletRequest request  ServletResponse response     
  11.             FilterChain chain) throws IOException  ServletException     
  12.         //用init方法取得的charset覆蓋被拦截下来的request对象的charset    
  13.         request setCharacterEncoding(this charset);    
  14.         //将请求移交给下一下过滤器 如果还有的情况下     
  15.         chain doFilter(request  response);    
  16.         
  17.    
  18.     @Override    
  19.     public void init(FilterConfig config) throws ServletException     
  20.         //从web xml中的filter的配制信息中取得字符集    
  21.         this charset = config getInitParameter("charset");    
  22.         
  23.    
  24. public class EncodingFilter implements Filter  private String charset; @Override public void destr
  25. oy()  // TODO Auto generated method stub  @Override public void doFilter(ServletRequest req
  26. uest  ServletResponse response  FilterChain chain) throws IOException  ServletException  //用init方
  27. 法取得的charset覆蓋被拦截下来的request对象的charset request setCharacterEncoding(this charset); //将
  28. 请求移交给下一下过滤器 如果还有的情况下  chain doFilter(request  response);  @Override pub
  29. lic void init(FilterConfig config) throws ServletException  //从web xml中的filter的配制信息中取得字
  30. 符集 this charset = config getInitParameter("charset");    

  要想这个过滤器生效 还得到web xml里加入下面的配制信息

  Web xml代码

  

  1. <filter>    
  2.    <filter name>EncodingFilter</filter name>    
  3.    <filter class>cn eric encodingtest filter EncodingFilter</filter class>    
  4.    <init param>    
  5.        <param name>charset</param name>    
  6.        <param value>UTF </param value>    
  7.    </init param>    
  8. </filter>    
  9. <filter mapping>    
  10.    <filter name>EncodingFilter</filter name>    
  11.    <url pattern>/*</url pattern>    
  12. </filter mapping>   
  13. <filter> <filter name>EncodingFilter</filter name> <filter class>cn eric encodingtest filter Encodi
  14. ngFilter</filter class> <init param> <param name>charset</param name> <param value>UT
  15. F </param value> </init param> </filter> <filter mapping> <filter name>EncodingFilter</filt
  16. er name> <url pattern>/*</url pattern> </filter mapping>  

   直接使用URL后接参数的形式(超级链接)

  有些时候可能会遇到通过一个超级链接来把参数传到下一个页面 而刚好这个参数的值有可能会出现中文的情况 就像下面这样

  

  1. <a href=" /jstlresult jsp?content=世界杯">Go South Africa 

  跟form提交有些不同的是 当你点击这个超级链接后在浏览器的地址栏里看到的是世界杯 而不是%E %B % %E % % C%E % D%AF

  这里浏览器并没有帮我们把这个转化工作搞定 所以这里要自己动手 丰衣足食了 做法如下

  

  1. <a href=" /jstlresult jsp?content=<%=java net URLEncoder encode("世界杯" "utf ") %>">Go South Africa 

  这样的话在第二个页面就能使用

  

  1. <%String str = new String(request getParameter("content") getBytes("ISO ") "utf "); %> 

  的方法来正确的得到这个参数值了

  总结一下

   post提交的方式 使用过滤器 将到达页面前的request对象中的字符编码设定成跟你页面统一的编码

   get提交的方式 <%String str = new String(request getParameter("content") getBytes("ISO ") "utf "); %>这样的字符串重组的方法

cha138/Article/program/Java/JSP/201311/19243

相关参考

知识大全 常见JSP中文乱码例子及其解决方法

常见JSP中文乱码例子及其解决方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  JSP开发应用

知识大全 如何解决JSP页面显示乱码问题[2]

如何解决JSP页面显示乱码问题[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 如何解决JSP页面显示乱码问题[1]

如何解决JSP页面显示乱码问题[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n

知识大全 jsp如何解决Form表单乱码问题

jsp如何解决Form表单乱码问题  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  网站程序中的F

知识大全 JSP中使用request乱码问题的解决

JSP中使用request乱码问题的解决  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  &nbs

知识大全 Jsp传递中文参数详解

Jsp传递中文参数详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  目前在jsp页面中传递中文

知识大全 JSP验证码大全之验证码使用与乱码解决

JSP验证码大全之验证码使用与乱码解决  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文中介绍

知识大全 JSP页面传值中文乱码的简单解决方法

JSP页面传值中文乱码的简单解决方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  源代码ajs

知识大全 如何解决html网页编码导致jsp页面乱码

  页面中这段不起眼的代码<metaequiv="ContentType"content="text/;charset=GBK">错把如果charset=GBK设置为charset=UTF

知识大全 jsp中文页面乱码与传参乱码

  页面乱码  这种乱码的原因是应为没有在页面里指定使用的字符集编码解决方法只要在页面开始地方用下面代码指定字符集编码即可代码如下   <%@pagecontentType="text