常 见的 Tomcat 5 表单编码提交后乱码的解决方案有很多, 有改 Tomcat Connector 属性的, 有加过滤器的. 但是 Tomcat 自带的那个过滤器只解决了 POST 方式的乱码却不能处理 GET 方式的乱码. 在这里那我就给出一个不需要修改任何 Tomcat 配置文件的完美解决中文问题的过滤器的代码:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <title>表单测试页面</title> </head> <body> <form action="action.jsp" > GET 方式: <input type=text name="name" value ="GET 中文" > <input type=submit> </form> <form action="action.jsp" method="POST" > POST 方式: <input type=text name="name" value ="POST 中文" > <input type=submit> </form> </body> </html>
和普通的表单没有任何区别.
然后就是表单提交页面 action.jsp:
<%@ page language="java" pageEncoding="GBK" %> <html> <body> 参数: <%=request.getParameter("name" ) %> <br> </body> </html>
接着是过滤器的配置文件 web.xml (用 2.5 版本也可以):
<? xml version ="1.0" encoding ="UTF-8" ?> < web-app version ="2.4" xmlns ="http://java.sun.com/xml/ns/j2ee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" > < filter > < filter-name > TomcatFormFilter</ filter-name > < filter-class > filters.TomcatFormFilter</ filter-class > </ filter > < filter-mapping > < filter-name > TomcatFormFilter</ filter-name > < url-pattern > *.jsp</ url-pattern > </ filter-mapping > < welcome-file-list > < welcome-file > index.jsp</ welcome-file > </ welcome-file-list > </ web-app >
最后最关键的就是我们的过滤器代码了, 对 GET 方式使用请求包装器, 而 POST 方式则用 setCharacterEncoding():
package filters; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; public class TomcatFormFilter implements Filter { /** * Request.java * 对 HttpServletRequestWrapper 进行扩充, 不影响原来的功能并能提供所有的 HttpServletRequest * 接口中的功能. 它可以统一的对 Tomcat 默认设置下的中文问题进行解决而只需要用新的 Request 对象替换页面中的 * request 对象即可. */ class Request extends HttpServletRequestWrapper { public Request(HttpServletRequest request) { super(request); } /** * 转换由表单读取的数据的内码. * 从 ISO 字符转到 GBK. */ public String toChi(String input) { try { byte [] bytes = input.getBytes("ISO8859-1" ); return new String(bytes, "GBK" ); } catch (Exception ex) { } return null ; } /** * Return the HttpServletRequest holded by this object. */ private HttpServletRequest getHttpServletRequest() { return (HttpServletRequest)super.getRequest(); } /** * 读取参数 -- 修正了中文问题. */ public String getParameter(String name) { return toChi(getHttpServletRequest().getParameter(name)); } /** * 读取参数列表 - 修正了中文问题. */ public String[] getParameterValues(String name) { String values[] = getHttpServletRequest().getParameterValues(name); if (values != null ) { for (int i = 0; i < values.length; i++) { values[i] = toChi(values[i]); } } return values; } } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpreq = (HttpServletRequest)request; if (httpreq.getMethod().equals("POST" )) { request.setCharacterEncoding("GBK" ); } else { request = new Request(httpreq); } chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { } }
怎么样, 是不是很简单也很方便呢?