`
cpop
  • 浏览: 9385 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解决jsp参数传递乱码时的问题

    博客分类:
  • java
阅读更多
    乱码的出现根本原因在于编码和解码使用了不同的编码方案。比如用GBK编码的文件,用UTF-8去解码结果肯定都是火星文。所以要解决这个问题,中心思想就在于使用统一的编码方案。

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

1.表单(form)的提交实现参数页面间的传递
在介绍表单传递参数的内容之前,先来了解一些预备知识。表单的提交方式和请求报文中对汉字的处理。

表单(POST)的提交方式:
    通常使用的表单的提交方式主要是:post和get两种。两者的区别在于:post方式是把数据内容放在请求的数据正文部分,没有长度的限制;get方式则是把数据内容直接跟在请求的头部的URL后面,有长度的限制。下面是同一个页面两种方式的请求报许文。
Requesttest.jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
<html>   
<head>   
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
<title>Insert title here</title>   
</head>   
<body>   
<%-- post方式提交表单 --%>   
<form action="http://localhost:8888/EncodingTest/requestresult.jsp" method="post">   
    UserName:<input type="text" name="username"/>   
    Password:<input type="password" name="password"/>   
    <input type="submit" value="Submit">   
</form>   
</body>   
</html>  
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%-- post方式提交表单 --%> <form action="http://localhost:8888/EncodingTestb/requestresult.jsp" method="post"> UserName:<input type="text" name="username"/> Password:<input type="password" name="password"/> <input type="submit" value="Submit"> </form> </body> </html> 

在上面的请求页面的username输入框里输入的是“世界杯”三个汉字,password输入框中输入"123"后按下Submit按钮提交请求。截获到的请求报文如下:
Post方式的请求报文代码:
引用
POST /EncodingTest/requestresult.jsp HTTP/1.1 
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*  
Referer: http://localhost:8080/TomcatJndiTest/requesttest.jsp  
Accept-Language: zh-cn  
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; aff-kingsoft-ciba; .NET CLR 2.0.50727)  
Content-Type: application/x-www-form-urlencoded  
Accept-Encoding: gzip, deflate  
Host: localhost:8888 
Content-Length: 49 
Connection: Keep-Alive  
Cache-Control: no-cache  
 
username=%E4%B8%96%E7%95%8C%E6%9D%AF&password=123
POST /EncodingTest/requestresult.jsp HTTP/1.1 Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */* Referer: http://localhost:8080/TomcatJndiTest/requesttest.jsp Accept-Language: zh-cn User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; aff-kingsoft-ciba; .NET CLR 2.0.50727) Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Host: localhost:8888 Content-Length: 49 Connection: Keep-Alive Cache-Control: no-cache username=%E4%B8%96%E7%95%8C%E6%9D%AF&password=123


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

get方式:
引用
GET /EncodingTest/requestresult.jsp?username=%E4%B8%96%E7%95%8C%E6%9D%AF&password=123 HTTP/1.1 
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*  
Referer: http://localhost:8080/TomcatJndiTest/requesttest.jsp  
Accept-Language: zh-cn  
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; aff-kingsoft-ciba; .NET CLR 2.0.50727)  
Accept-Encoding: gzip, deflate  
Host: localhost:8888 
Connection: Keep-Alive 
GET /EncodingTest/requestresult.jsp?username=%E4%B8%96%E7%95%8C%E6%9D%AF&password=123 HTTP/1.1 Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */* Referer: http://localhost:8080/TomcatJndiTest/requesttest.jsp Accept-Language: zh-cn User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; aff-kingsoft-ciba; .NET CLR 2.0.50727) Accept-Encoding: gzip, deflate Host: localhost:8888 Connection: Keep-Alive



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

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

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

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

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

方案一:
<%String str = new String(request.getParameter("username").getBytes("ISO-8859-1"),"utf-8"); %>   
Username:<%=str %>  
<%String str = new String(request.getParameter("username").getBytes("ISO-8859-1"),"utf-8"); %> Username:<%=str %> 

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

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

方案二:
<%request.setCharacterEncoding("UTF-8"); %>  
<%request.setCharacterEncoding("UTF-8"); %> 

方案二是在页面的最开始或者是在该页面中使用的第一个request.getParameter("")方法之前加上上述一段代码,它的作用是用作为参数传入的编码集去覆盖request对象中的默认的"ISO-8859-1"编码集。这样request.getParameter("")方法就会用新的编码集去解码,因为"UTF-8"支持中文,所以作为参数传过来的“世界杯”三个汉字就能正确的接收到了。但关于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-8"); %>这段代码,这样做是不是也挺累的,所以我们想到了使用过滤器来帮助我们做这件事儿,那就清爽、简单多了。
EncodingFilter.java:
public class EncodingFilter implements Filter {   
       
    private String charset;   
    @Override   
    public void destroy() {   
        // TODO Auto-generated method stub   
    }   
  
    @Override   
    public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain chain) throws IOException, ServletException
 {   
        //用init方法取得的charset覆盖被拦截下来的request对象的charset
        request.setCharacterEncoding(this.charset);   
        //将请求移交给下一下过滤器,如果还有的情况下。   
        chain.doFilter(request, response);   
    }   
  
    @Override   
    public void init(FilterConfig config) throws ServletException {   
        //从web.xml中的filter的配制信息中取得字符集   
        this.charset = config.getInitParameter("charset");   
    }   
}  

要想这个过滤器生效,还得到web.xml里加入下面的配制信息。
Web.xml:
<filter>   
   <filter>
		<filter-name>EncodingFilter</filter-name>
		<filter-class>cn.eric.encodingtest.filter.EncodingFilter
		</filter-class>
		<init-param>
			<param-name>charset</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>EncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter>
		<filter-name>EncodingFilter</filter-name>
		<filter-class>cn.eric.encodingtest.filter.EncodingFilter
		</filter-class>
		<init-param>
			<param-name>charset</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>EncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


总结一下:
    1、post提交的方式:使用过滤器,将到达页面前的request对象中的字符编码设定成跟你页面统一的编码。
    2、get提交的方式:<%String str = new String(request.getParameter("content").getBytes("ISO-8859-1"),"utf-8"); %>这样的字符串重组的方法。
    3、超级链接方式:先将链接url中的汉字用java.net.URLEncoder.encode("paramValue","charset")方法处理一下,下面的做法参照2。

<完>
转自:http://www.blogjava.net/tbwshc/archive/2012/06/18/381005.html
分享到:
评论

相关推荐

    JSP中文乱码问题解决办法

    JSP 中文乱码问题解决办法 JSP 页面中中文乱码问题是指在 JSP 页面中使用中文时,页面显示乱码的现象。这种问题的解决办法可以从多方面入手,包括设置页面的字符编码、使用 POST 方式提交表单、使用 GET 方式提交...

    Jsp页面在URL中传递参数会出现乱码问题解决

    在Web开发中,尤其是使用Java JSP技术时,我们可能会遇到...通过以上方法,我们可以有效地解决JSP页面在URL中传递参数时出现的乱码问题。在实际开发中,理解字符编码的工作原理和处理方式,对于避免这类问题至关重要。

    解决jsp提交乱码的问题

    本篇文章将详细介绍如何解决JSP页面提交时出现的乱码问题,包括GET请求和POST请求两种常见的情况。 #### 一、问题背景与分析 1. **GET请求乱码**: - GET请求是通过URL来传递参数的,这些参数通常会以编码的形式...

    jsp传值中文乱码问题解决方法示例介绍.docx

    在开发Web应用时,尤其是使用Java的JSP技术,开发者经常会遇到中文乱码的问题。这是因为字符编码不一致导致的,特别是在处理用户输入或从数据库获取数据时。...同时,理解字符编码原理,有助于更好地排查和解决问题。

    jsp中文乱码问题解决

    在jsp页面中,传递参数时也可能出现中文乱码问题。解决方法是修改Tomcat的server.xml文件,添加URLEncoding=”utf-8”参数,以指定Tomcat的编码方式为UTF-8。例如:“8080” protocol=“HTTP/1.1” maxThreads=“150...

    JSP-GET-POST传递的乱码问题

    然而,在处理中文参数时,尤其是通过GET和POST方法传递时,经常会出现乱码问题。这通常是由于字符编码不一致或者处理不当导致的。以下是对这一问题的详细解析: 首先,我们需要理解字符编码的基本概念。在Web中,...

    JSP页面中文乱码几个解决办法

    当JSP页面在浏览器中显示乱码时,首先需要确保JSP文件在本地存储时使用的编码是GBK。在JSP页面顶部添加`&lt;%@ pageEncoding="GBK" %&gt;`指令,指定页面的编码格式为GBK,这有助于确保服务器解析JSP时使用正确的编码。 ...

    几种常用解决jsp中文乱码的方案

    JSP 中文乱码是动态网站开发中经常遇到的问题,本文将从产生 JSP 中文乱码的四种类型入手,分析乱码产生的原因,并给出消除乱码的具体方法。 一、页面中文乱码的处理 JSP 采用 ISO-8859-1 作为默认的页面字符编码...

    JSP乱码 N种解决方案

    在开发Java Web应用程序时,JSP(JavaServer Pages)页面经常遇到字符编码问题,导致页面显示乱码。本文将深入探讨“JSP乱码”的多种解决方案,并提供实用的解决策略。 1. **理解字符编码的基本概念** - 字符编码...

    Jsp乱码问题解决

    2. **参数传递编码问题:** 在处理表单提交的过程中,如果没有对参数进行正确的编码转换,也会导致乱码问题。 **解决方法:** 在处理表单提交的数据之前,可以使用`request.setCharacterEncoding()`方法来指定请求...

    教学视频--JSP中URL传递中文乱码问题的解决演示.rar

    然而,在实际操作中,我们时常会遇到一个问题,那就是当JSP页面通过URL传递包含中文字符的参数时,可能会出现乱码现象。这个问题主要源于HTTP协议的特性以及字符编码的处理不当。本教学视频将详细讲解如何解决JSP中...

    JSP中文乱码问题解决方法小结

    3. **中文作为参数传递乱码** 当中文参数通过URL传递时,可能会因URL编码不一致产生乱码。为避免这个问题,需要在发送请求前使用`java.net.URLEncoder.encode()`对中文参数进行编码,例如`RearshRes.jsp?keywords=...

    jsp eclipse乱码问题

    2. **参数传递乱码**:在表单提交或URL传参过程中,中文等非ASCII字符无法正确识别或解析。 #### 二、乱码产生的原因 1. **编码设置不一致**:JSP页面、客户端(浏览器)以及服务器端的编码设置如果不统一,则会...

    jsp使用URL编码传递中文参数乱码问题

    jsp使用URL编码传递中文参数乱码问题

    jsp页面传值中文乱码问题处理.docx

    jsp页面传值中文乱码问题处理 在 JSP 页面中传值时,中文字符可能会出现乱码问题,这...JSP 页面传值中文乱码问题可以通过修改编码方式、设置输出编码、接收参数编码、Get 提交编码和数据库连接参数编码等方式来解决。

    JSP中解决中文乱码的万能方法

    在JSP开发过程中,中文乱码问题是一个常见的技术难题,尤其在处理客户端与服务器之间的数据交互时更为突出。本文将详细介绍几种有效的解决方案,帮助开发者应对各种场景下的乱码问题。 #### 一、解决服务器响应中文...

    解决jsp中文乱码问题

    本文将详细介绍如何解决JSP中中文乱码的问题,包括页面传递中文参数时可能出现的乱码情况。 #### 一、中文乱码的原因分析 中文乱码主要是因为字符编码不一致导致的。当数据从一个环境传递到另一个环境时,如果这两...

    JSP中汉字乱码现象分析与解决.pdf

    综上所述,解决JSP中的中文乱码问题主要涉及以下几个方面:合理设置JSP文件和响应的编码方式、注意文件头部的BOM、确保客户端和服务器端之间的编码方式一致、正确处理GET和POST请求中的中文参数。通过上述措施,可以...

    JSP中文乱码常见3个例子及其解决方法.docx

    解决方法是在接收参数的JSP页面中,同样指定字符集,确保接收和显示中文参数时不会乱码。同时,也可以在服务器端设置响应头,指定Content-Type,如下: ```jsp ;charset=UTF-8" %&gt; response.setCharacterEncoding...

Global site tag (gtag.js) - Google Analytics