jsp:forward和jsp:include乱码原理一样,这里以jsp:forward来说明。
jsp的forward指令用于将页面响应转发到另外的页面,可以转发到静态的HTML页面,也可以转发到动态的JSP页面,还可以转发到容器中的Servlet。在进行转发时,可以通过jsp:param指令增加额外的请求参数,增加请求参数可以通过HttpServletRequest类的getParameter()方法获取。
但是增加的参数包含中文时,通过request获取的参数乱码,检查执行jsp:forward转发的页面和目标页面的编码,统一都为utf-8编码,但是中文还是乱码。代码如下:
index.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>测试JSP的forward指令</title> </head> <body> <jsp:forward page="in1.jsp"> <jsp:param value="guoguo蝈蝈" name="param"/> </jsp:forward> </body> </html>in1.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>forward</title> </head> <body> <% out.print("我是in1.jsp文件的内容 "); out.print("参数为:"+request.getParameter("param")); %> </body> </html>
JSP的page指令里设置的两个编码:
contentType="text/html; charset=UTF-8" 设置的response的编码
pageEncoding="utf-8" 设置的jsp文件的编码
两者的区别可以参考:jsp通过include指令引入html乱码的解决方法 http://blog.csdn.net/gnail_oug/article/details/51707061
通过查看jsp翻译后的Servlet源码,可以发现jsp:forward时是使用request的编码对jsp:param参数进行URLEncode的,如下:
jsp页面代码:
<jsp:forward page="in1.jsp"> <jsp:param value="guoguo蝈蝈" name="param"/> </jsp:forward>
翻译后的Servlet代码:
if (true) { <span style="white-space:pre"> </span>_jspx_page_context.forward("in1.jsp" + "?" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("param", request.getCharacterEncoding())+ "=" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("guoguo蝈蝈", request.getCharacterEncoding())); <span style="white-space:pre"> </span>return; }默认情况下,request是没有设置编码的,通过查看JspRuntimeLibrary类的URLEncode("",""),可以发现当编码为空时使用默认编码iso-8859-1,JspRuntimeLibrary类的URLEncode()方法内容如下:
public static String URLEncode(String s, String enc){ if (s == null) { return "null"; } if (enc == null) { enc = "ISO-8859-1"; } //下面内容省略 }由于iso-8859-1不支持中文,所以导致传递的中文参数乱码。
问题原因找到了,所以只需将request的字符集设置为utf-8即可,即在执行jsp:forward的页面添加如下代码:
<% request.setCharacterEncoding("utf-8"); %>需要注意的是:
1、设置编码的代码是在jsp:forward标签所在的页面,而不是转发的目标页面通过request取值的地方,因为这时已经乱码了再设置编码也没用了。
2、设置编码的代码一定要在jsp:forward标签之前,否则设置的没用
完整的代码如下:
index.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>测试JSP的forward指令</title> </head> <body> <% request.setCharacterEncoding("utf-8"); %> <jsp:forward page="in1.jsp"> <jsp:param value="guoguo蝈蝈" name="param"/> </jsp:forward> </body> </html>in1.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>forward</title> </head> <body> <% out.print("我是in1.jsp文件的内容 "); out.print("参数为:"+request.getParameter("param")); %> </body> </html>