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;

public class CharacterEncodingFilter implements Filter 
{

	protected String encoding = null;

	protected FilterConfig filterConfig = null;

	protected boolean ignore = true;

	public void init(FilterConfig filterConfig) throws ServletException 
	{
		this.filterConfig = filterConfig;
		this.encoding = filterConfig.getInitParameter("encoding");
		String value = filterConfig.getInitParameter("ignore");
		if (value == null)
			this.ignore = true;
		else if (value.equalsIgnoreCase("true"))
			this.ignore = true;
		else if (value.equalsIgnoreCase("yes"))
			this.ignore = true;
		else
			this.ignore = false;

	}

	protected String selectEncoding(ServletRequest request) 
	{
		return (this.encoding);
	}
	
	public void destroy() 
	{

		this.encoding = null;
		this.filterConfig = null;

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException 
	{

		if (ignore || (request.getCharacterEncoding() == null)) 
		{
			String encoding = selectEncoding(request);
			if (encoding != null)
			{
				//核心代码, r
				request.setCharacterEncoding(encoding);
			}
		}

		chain.doFilter(request, response);
	}
	

}


    1、request.setCharacterEncoding

        1)设置从request中取得的值时使用的编码。

        2)该过滤器只能处理POST提交造成的中文乱码,对GET提交造成的中文代码无效。


    POST请求分析:表单提交,浏览器根据当前页面编码方案对数据进行编码(页面编码方案可以通过pageEncoding属性进行设置,例如pageEncoding="UTF-8"),如果不调用request.setCharacterEncoding设置解码方案,那么则默认使用"ISO-8859-1"对数据进行解码,所以造成中文乱码。


    POST请求的解码机制:在第一次调用request.getParameter时,tomcat根据request.setCharacterEncoding设置好的解码方案对所有数据进行解码,而后续调用request.getParameter则不再进行解码,所以必须在第一次调用request.getParameter之前, 必须调用request.setCharacterEncoding进行解码方案设置。

        

   GET请求中文乱码解决方案:需要在Tomcat的server.xml中配置,添加属性 URIEncoding="UTF-8"解决GET提交乱码问题。代码如下:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" 
redirectPort="8443" URIEncoding="UTF-8"/>


    GET请求的解码机制:众所周知,GET提交的内容会显示在浏览器URL中,以ASCII字符形式进行数据传输,到了tomcat中,会根据server.xml中设置的URIEncoding指定的解码方案进行解码。由于tomcat知道GET提交的数据早就进行了解码,所以调用request.getParameter时就不会再对数据进行解码,所以request.setCharacterEncoding自然就无效。

    



    2、response.setCharacterEncoding

    response.setContentType:设置HTTP响应的编码,同时通知浏览器显示时使用的编码。

    response.setCharacterEncoding:设置HTTP响应的编码,如果之前使用了response.setContentType设置了编码方案,则可以使用response.setCharacterEncoding覆盖之前的设置,这两个方法,必须在reponse提交之前或者response.getWriter之前调用。否则无效。