11.全站乱码过滤器

全站乱码过滤器

我们可以开发一个Filter,拦截所有的动态web资源,在动态web资源执行之前,解决好乱码,从而一劳永逸的解决全站乱码问题。

对于响应数据乱码,只需要设置Content-Type即可解决乱码。

对于请求参数乱码,如果是POST提交,可以一行代码解决,如果是GET提交需要手动的编解码解决乱码。

代码实现

package cn.bingou.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

// 实现 javax servlet 包中的Filter
public class EncodingFilter implements Filter {

    private String encode=null; // 使用全局字的符集
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        // 1.解决应答乱码  
        response.setContentType("text/html;charset="+encode);// 设置响应类型为text/html
        // 2.解决请求乱码 -> 使用MyRequest替代request
        MyRequest req=new MyRequest((HttpServletRequest) request);
        
        // 放行请求
        chain.doFilter(req, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 通过fileterConfig对象获取ServletContext对象
        ServletContext sc=filterConfig.getServletContext();
        // 通过sc获取web.xml配置的初始化参数,给encode属性赋值
        encode=sc.getInitParameter("encode");
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    
    class MyRequest extends HttpServletRequestWrapper{

        // 该变量表明paramMap集合是否已经被进行过编码
        private boolean hasEncode=false;
        
        public MyRequest(HttpServletRequest request) {
            super(request);
        }
        
        @Override
        public String getParameter(String name){
            // 调用本类重写的方法,获取已经进行过手动编码的map集合
            Map<String,String[]> paramMap=this.getParameterMap();
            // 从集合中获取name对应的value
            String[] value=paramMap.get(name);
            if(value!=null){
                // 如果数组部位null,返回数组中的第一个元素
                return value[0];
            }
            // 如果数组为null,返回数组中的第一个元素
            return null;
        }
        
        @Override
        public Map<String,String[]> getParameterMap(){
            // 获取被装饰者 -> request对象
            ServletRequest req=this.getRequest();
            // 调用被装饰者的方法,获取保存了请求参数的map
            Map<String, String[]> paramMap=req.getParameterMap();
            if(this.hasEncode==false){ // 还没有进行过手动编码
                // 遍历这个map集合,进行手动编解码
                for(Entry<String,String[]> entry:paramMap.entrySet()){
                    // 获取一个请求参数对应的值
                    String[] values=entry.getValue();
                    if(values!=null){
                        // 对数组中的所有值进行手动编码
                        for(int i=0;i<values.length;i++){
                            try {
                                values[i]=new String(values[i].getBytes("iso8859-1"),encode);
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                this.hasEncode=true;
            }
            return paramMap;
        }
        
        @Override
        public String[] getParameterValues(String name){
            return this.getParameterMap().get(name);
        }
    } 
}

注意:千万要看好编码标准8859-1,我就写反了,找了一下午bug才找到!

web.xml配置

  <!-- 配置过滤器 -->
  <filter>
      <filter-name>EncodingFilter</filter-name>
      <filter-class>cn.bingou.filter.EncodingFilter</filter-class>
  </filter>
  
  <!-- 配置过滤器拦截的url -->
  <filter-mapping>
      <filter-name>EncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
原文地址:https://www.cnblogs.com/chuijingjing/p/9812494.html