全站乱码过滤器
我们可以开发一个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>