全站乱码解决 详细过程【filter的使用】

首先贴上源码

public class EncodeFilter implements Filter {
	private FilterConfig config = null;
	private ServletContext context = null;
	private String encode = null;
	public void destroy() {
		
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		//--响应乱码解决
		response.setCharacterEncoding(encode);
		response.setContentType("text/html;charset="+encode);
		//--利用装饰设计模式改变request对象和获取请求参数相关的方法,从而解决请求参数乱码问题
		chain.doFilter(new MyHttpServletRequest((HttpServletRequest) request), response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		this.config = filterConfig;
		this.context = filterConfig.getServletContext();
		this.encode = context.getInitParameter("encode");
	}

	private class MyHttpServletRequest extends HttpServletRequestWrapper{
		private  HttpServletRequest request = null;
		private boolean isNotEncode = true;
		public MyHttpServletRequest(HttpServletRequest request) {
			super(request);
			this.request = request;
		}
		
		@Override
		public Map<String,String[]> getParameterMap() {
			try{
				if(request.getMethod().equalsIgnoreCase("POST")){
					request.setCharacterEncoding(encode);
					return request.getParameterMap();
				}else if(request.getMethod().equalsIgnoreCase("GET")){
					Map<String,String[]> map = request.getParameterMap();
					if(isNotEncode){
						for(Map.Entry<String, String[]> entry : map.entrySet()){
							String [] vs = entry.getValue();
							for(int i=0;i<vs.length;i++){
								vs[i] = new String(vs[i].getBytes("iso8859-1"),encode);
							}
						}
						isNotEncode = false;
					}
					return map;
				}else{
					return request.getParameterMap();
				}
			}catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		
		@Override
		public String[] getParameterValues(String name) {
			return getParameterMap().get(name);
		}
		
		@Override
		public String getParameter(String name) {
			return getParameterValues(name) == null ? null : getParameterValues(name)[0];
		}
		
	} 
}

配置文件:

context-param>
  		<description>全站编码配置</description>
  		<param-name>encode</param-name>
  		<param-value>utf-8</param-value>
  </context-param>
  <filter>
  		<description>全站乱码过滤器</description>
  		<filter-name>EncodeFilter</filter-name>
  		<filter-class></filter-class>
  </filter>
  
  <filter-mapping>
  		<filter-name>EncodeFilter</filter-name>
  		<url-pattern>/*</url-pattern>
  </filter-mapping>

配置文件不做过多介绍

一:首先实现filter接口,重写需要的方法(分别是destory,doFilter,init)

destory方法 如果有需要,可以自己重写,这里不做介绍。

init方法,Filter对象在tomcat服务器启动时 创建,调用init方法  (只会创建一个对象,init方法执行一次)用于初始化

doFilter  每次拦截目标资源时,执行。也正是我们需要进行大改造的方法。

二:定义三个变量config,context,encode。用于初始化数据。在init方法中进行,过于简单不在赘述

(应该知道:filterConfig可以得到servletContext)

三:在doFilter方法中解决request和response乱码问题。我们知道response解决乱码简单。通过两行代码就可以搞定

        response.setCharacterEncoding(encode);
        response.setContentType("text/html;charset="+encode);

但是request就没那么简单了,所以我们将请求的参数取出来进行编码,解决乱码问题。这时候就需要

HttpServletRequestWrapper了。

四:利用装饰设计模式改变request对象和获取请求参数相关的方法,从而解决请求参数乱码问题。

自定义一个MyHttpServletReques继承HttpServletRequestWrapper,修改我们需要修改的方法

分别是MyHttpServletRequest,getParameterMap(),getParameterValues(String name),getParameter(String name)

MyHttpServletRequest构造方法,不说了

getParameterMap()返回的类型是Map<String,String[]>。我需要做的改造是

如果post请求,直接设计编码request.setCharacterEncoding(encode);

如果get请求,将map中的值一个个取出来进行重新编码。

(这里的方法比较有趣,需要注意下Map.Entry<String, String[]> entry : map.entrySet(),用的是这种方式。map.entrySet()返回的是一个Map.Entry<T, T[]>类型,所以可以用entry变量接收。需要注意的是Entry是Map的一个内部接口。然后这个entry有两个比较牛逼的的方法,可以直接取出值String [] vs = entry.getValue();和直接获得键String [] vs = entry.getKey();)

五:另外两个方法就自己看吧简单易懂。

猜你喜欢

转载自blog.csdn.net/BadRibbit/article/details/81533651