下面的任何一条缺一不可,注意,我之所以全部都用的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
foo-servlet2 org.lxh.servletdemo.FooServlet2 foo-servlet2 /FooServlet2 charset-encoding org.lxh.filterdemo.CharacterEncodingFilter encoding UTF-8 enable true charset-encoding /*
input.html
Insert title here
input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here <% String str = (String) request.getAttribute("info") ; out.println(""+str+"
") ; %>
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); } }