JSP/Servlet中文乱码处理总结
下面的任何一条缺一不可,注意,我之所以全部都用的XXX,意思就是这几个最好全部都一致!
1、HTML中要用meta content="text/html; charset=XXX"来指出HTML页面的编码为XXX,XXX必须和HTML文件本身的编码一致!
2、JSP页面中必须要出现pageEncoding="XXX"用来指出JSP文件本身的编码,这样JSP文件在编译为java文件的时候才不会有乱码(并且JSP文件对应的java文件是UTF-8的编码),然后JSP文件对应的java文件被编译为class文件,仍然是UTF-8编码,最后class文件被web-container(例如tomcat)执行,得到的结果tomcat会给返回到客户端浏览器上,这时就需要contentType="...; charset=XXX"来指定编码;如果是contentType="text/html",也可以用meta来指定charset=XXX,
3、JSP和Servlet中,必须确保在用request取出参数之前调用request.setCharacterEncoding("XXX"),这个如果不希望重复写这个代码,就采取在filter中写上这个代码
4、response.setCharacterEncoding和response.setContentType()暂时不明真相
比如下面有个测试的典型,input.html, input.jsp,这些页面的pageEncoding,charset都事先写在代码里了,一个不缺,并且文件本身的编码与之一致,然后你可以看看打开、关闭filter的效果有什么不同
文件结构如下
/WebContent/WEB-INF/web.xml
/WebContent/9.10.3/input.html
/WebContent/9.10.3/input.jsp
web.xml
<!-- FooServlet2 --> <servlet> <servlet-name>foo-servlet2</servlet-name> <servlet-class> org.lxh.servletdemo.FooServlet2 </servlet-class> </servlet> <servlet-mapping> <servlet-name>foo-servlet2</servlet-name> <url-pattern>/FooServlet2</url-pattern> </servlet-mapping> <!-- encoding filter --> <filter> <filter-name>charset-encoding</filter-name> <filter-class>org.lxh.filterdemo.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>enable</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>charset-encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
input.html
<!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> <form action="../FooServlet2" method="post"> <!-- 输入中文来测试 --> 请输入要显示的内容:<input type="text" name="info"> <input type="submit" value="显示"> </form> </body> </html>
input.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> <!-- 注意这里并没有调用request.setCharacterEncoding(), 你把CharacterEncodingFilter关闭了试试,看看结果有什么 不一样 --> <% String str = (String) request.getAttribute("info") ; out.println("<h1>"+str+"</h1>") ; %> </body> </html>
FooServlet2.java
package org.lxh.servletdemo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.*; public class FooServlet2 extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 在这里也没有调用request.setCharacterEncoding(), // 你把CharacterEncodingFilter关闭了试试,看看结果有什么 // 不一样 String info = req.getParameter("info"); if (info != null) { info = info + "--- 这是一条小尾巴"; System.out.println(this + ", " + info); req.setAttribute("info", info); req.getRequestDispatcher("/9.10.3/input.jsp").forward(req, resp); } } @Override public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
CharacterEncodingFilter.java
package org.lxh.filterdemo; import java.io.IOException; import java.nio.charset.Charset; 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.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CharacterEncodingFilter implements Filter { protected String encoding = null; protected FilterConfig filterConfig = null; protected boolean enable = false; public void destroy() { this.encoding = null; this.filterConfig = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (this.enable) { String encoding = this.selectEncoding(request); if (encoding != null && !encoding.equals("")) { System.out.println(this + ": " + encoding); request.setCharacterEncoding(encoding); //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(). // response.setCharacterEncoding(encoding); // 暂时不太清楚 } } // Pass control on to the next filter chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; this.encoding = filterConfig.getInitParameter("encoding"); if (!Charset.isSupported(encoding)) { encoding = null; } String enableString = filterConfig.getInitParameter("enable"); if (enableString.equalsIgnoreCase("true")) { this.enable = true; } else { this.enable = false; } } protected String selectEncoding(ServletRequest request) { return (this.encoding); } }