计算机生于美国,英语是他的母语,而英语以外的其它语言对他来说都是外语。他跟我们一样,不管外语掌握到什么程度,也不会像母语那样使用得那么好,时常也会出一些“拼写错误”问题。
乱码的出现根本原因在于编码和解码使用了不同的编码方案。比如用GBK编码的文件,用UTF-8去解码结果肯定都是火星文。所以要解决这个问题,中心思想就在于使用统一的编码方案。
jsp页面间的参数传递有以下几种方式:1、表单(form)的提交。2、直接使用URL后接参数的形式(超级链接)。3、如果两个jsp页面在两 个不同的窗口中,并且这两个窗口是父子的关系,子窗口中的jsp也可以使用javascript和 DOM(window.opener.XXX.value)来取得父窗口中的jsp的输入元素的值。下面就前两种方式中出现的乱码问题做一下剖析。
1、表单(form)的提交实现参数页面间的传递
在介绍表单传递参数的内容之前,先来了解一些预备知识。表单的提交方式和请求报文中对汉字的处理。
表单的提交方式:
通常使用的表单的提交方式主要是: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方式的请求报文代码
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
以上报文内容,可以看出get方式的请求报文没有专门的数据部,数据是直接跟在url的后面。
请求报文中对汉字的处理:
从上面两种报文可以看出页面上输入的“世界杯”三个汉字被替换成了"%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")。 这样就能见到它的庐山真面目了。
方案一是一种比较万能的方法,不管是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代码
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");
}
}
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-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>
2、直接使用URL后接参数的形式(超级链接)。
有些时候可能会遇到通过一个超级链接来把参数传到下一个页面,而刚好这个参数的值有可能会出现中文的情况。就像下面这样:
<a href="./jstlresult.jsp?content=世界杯">Go South Africa
跟form提交有些不同的是:当你点击这个超级链接后在浏览器的地址栏里看到的是http://localhost:8080 /TomcatJndiTest/jstlresult.jsp?content=世界杯,而不是http://localhost:8080 /TomcatJndiTest/jstlresult.jsp?content=%E4%B8%96%E7%95%8C%E6%9D%AF
这里浏览器并没有帮我们把这个转化工作搞定,所以这里要自己动手,丰衣足食了。做法如下:
<a href="./jstlresult.jsp?content=<%=java.net.URLEncoder.encode("世界杯","utf-8") %>">Go South Africa
这样的话在第二个页面就能使用
<%String str = new String(request.getParameter("content").getBytes("ISO-8859-1"),"utf-8"); %>
的方法来正确的得到这个参数值了。
总结一下:
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。
转载至阳和移动开发
相关推荐
总结来说,理解和掌握JSP中的字符编码是每个Web开发者的基本技能。正确使用`getBytes()`方法,以及在请求、响应、文件、数据库等各个环节设定合适的编码,能够避免许多不必要的编码问题,提高应用的健壮性和用户体验...
综上所述,处理JSP中URL编码传递中文参数的关键在于理解字符编码的转换过程,并确保所有环节的编码一致。通过正确使用`URLEncoder.encode()`进行编码,以及适当地解码`request.getParameter()`返回的值,可以有效地...
JSP 页面中的字符编码方式与乱码解决方法 在 JSP 中,字符编码方式的设置是非常重要的,因为它直接影响着页面的显示效果。如果不正确地设置字符编码方式,可能会出现乱码问题。下面我们将详细介绍 JSP 中的字符编码...
### 知识点详解:JSP页面中文参数传递GET与POST...以上所述的知识点涵盖了JSP页面中文参数传递的主要挑战及解决方案,遵循这些指导原则,可以有效避免因字符编码问题导致的数据乱码,提升Web应用的健壮性和用户体验。
`<jsp:param>` 标签可以用来在使用 `<jsp:include>` 或 `<jsp:forward>` 动作指令时传递参数。这为开发者提供了一种更加灵活的方式来管理页面之间的数据交互。 **1. 使用 `<jsp:include>` 包含页面时传递参数** ``...
"JSP页面间传递参数实现的方法" JSP页面间传递参数是Web开发中的一项重要技术,以下是几种常见的JSP页面间传递参数实现的方法: 1. 直接在 URL 请求后添加参数 可以在 URL 请求后添加参数,如:<a href="thexuan....
在JavaServer Pages (JSP) 中,字符串截取是一项常见的任务,特别是在处理用户输入或显示数据时。JSP 提供了内置对象和脚本元素来处理字符串操作,其中包括字符串截取。下面我们将深入探讨如何在 JSP 页面中进行字符...
本文将深入探讨如何在Cognos与JSP之间通过URL传递参数。 1. **URL参数传递基础** URL(Uniform Resource Locator)是互联网上的资源定位符,它可以携带信息以传递给服务器。参数通常以问号(?)分隔,多个参数用&...
jsp使用URL编码传递中文参数乱码问题
其实 JSP/Servlet 的中文encoding 并没有想像的那么复杂,虽然定位和解决问题没有定规,各种运行环境也各不尽然,但后面的原理是一样的。了解字符集的知识是解决字符问题的基础。不过,随着中文字符集的变化,不仅仅...
在多个页面传递jsp参数在多个页面传递jsp参数
然而,在实际应用中经常会遇到一些特殊字符如“#”、“&”等,这些字符如果不经过适当的编码处理,在传递过程中可能会导致解析错误或丢失数据。本文将详细介绍如何在JSP中正确地处理这些特殊字符,确保URL传参的准确...
在IT开发环境中,字符编码的正确设置至关重要,尤其是在使用集成开发环境(IDE)如MyEclipse时。MyEclipse字符编码的设置对于处理各种类型的文本文件,尤其是涉及到中文字符的文件,有着决定性的影响。本篇文章将...
这是本人做的一个演示JSP如何传递参数的实例,里面介绍了JSP传递各种参数的5种方法,还有一种就是通过地址栏来传递,在这里里面没有体现。
### Tomcat字符编码总结 #### 一、引言 在Web开发中,字符编码问题一直是让人头疼的问题之一,尤其是在处理中文等多字节字符时。本文将深入探讨Tomcat环境中字符编码的相关知识点,并通过实际案例分析如何有效解决...
JSP页面中的字符编码方式与乱码解决方法 在 JSP/Servlet 中,字符编码方式是一个非常重要的概念,它直接关系到页面的正确显示和数据的传输。在 JSP/Servlet 中主要有四个地方可以设置编码,分别是 pageEncoding、...
项目编码统一使用GBK,这是一种简体中文的字符编码,适用于处理中文字符。然而,现代Web应用更倾向于使用UTF-8,因为它是国际化的标准,支持更多的字符集。 7. 运行环境: 项目原始运行于Tomcat服务器,这是一个...
- **乱码问题**:如果设置了正确的字符编码后仍然出现乱码,可能是其他地方也涉及到了字符编码的转换,如数据库连接、JSP页面编码等。需要检查整个流程中的所有编码设置是否一致。 - **多浏览器兼容性**:不同的...
在JSP开发中,数据的传递是常见的操作,但当涉及不同页面间的变量传递时,可能会遇到乱码问题,这主要是由于字符编码不一致导致的。本文将详细介绍如何解决JSP页面间传递变量时出现的乱码问题。 首先,我们来看方案...
1.传递参数: 代码如下: var pmt = ‘sensor=’+ encodeURI(encodeURI(sensor))+’&device=’+encodeURI(encodeURI(device))+’&instrument=’; pmt += encodeURI(encodeURI(instrument))+’&n=’+n+’&addDate=’+...