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>













Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐