全站乱码处理过滤器

全站乱码处理过滤器

这里小小的整理了一番,整理出了一个全站的乱码处理过滤器。
先来总结一下:相应参数乱码如下
1.响应参数乱码

response.getOutputStream().write("HttpResponse".getbytes());

(1)服务端在发送数据,数据使用的编码是GBK(字符串转成二进制数组调用的是getBytes(),这个方法如果不指定,将会使用默认的平台码GBK)
(2)浏览器自己有默认的编码(比如谷歌),如果不指定,默认使用utf-8来接收数据. 发送数据和接收数据使用的码表不一致造成乱码。
当然比较直观的解决方案就是设置服务器发送的时候的编码和客户端浏览器接受的编码一致,这样就从根本上解决了乱码问题。

    当然我们也还有别的方案处理乱码
    比如:response.setContentType("text/html;charset=utf-8");

– 这行代码有两个作用,既会通知服务器用utf-8来发送数据,也会通知浏览器使用utf-8来接收数据!

2.请求参数乱码
在通过request对象获取请求参数时, 如果参数中有中文数据, 在获取时就会出现乱码, 其原因是由于浏览器发送参数时(编码时)使用的码表 和 服务器在结束数据时(解码时)使用的码表不一致造成的!
(1)浏览器发送数据时使用的码表: 浏览器在发送数据时使用的码表取决于打开页面时使用的码表, 即浏览器使用什么编码打开页面, 就会使用相同的编码来发送数据. 这里使用的是utf-8这个码表!
服务器接收数据时使用的码表: 服务器在接收数据时默认使用iso8859-1来接收请求参数
解决方案:

request.setCharacterEncoding(“utf-8”);
 这行代码是通知服务器使用utf-8来接收请求实体内容中的数据.

而这两种问题每每出现的时候我们首先就要分析是哪一层到哪一层出现了乱码问题,一次一次的处理也导致了代码的冗余问题还有的时候我们需要修改服务器的配置文件,比如:Tomcat
而我总结的这个过滤器只需要添加到你的web应用里,再在web.xml上配置 一下即可实现。
下面放出完整代码

package com.tedu.jt.filter;
import java.io.IOException;
import java.util.Map;
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.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
/**
 * 处理全站乱码的过滤器
 *	1.处理请求参数乱码(GET和POST)
 *  2.处理响应正文乱码
 */
public class EncodingFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {}
	
	/* 处理所拦截到的请求的核心方法
	 * (相当于Servlet中的service方法) */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("EncodingFilter.doFilter()....");
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		/* POST:
		 * 在过滤器中处理请求参数乱码(只需要写一次, 所有被拦截到的资源的乱码问题都可以解决)
		 */
		request.setCharacterEncoding("utf-8");//针对POST提交
		
		/*
		 * 在过滤器中处理响应正文乱码(只需要写一次, 
		 *   所有被拦截到的资源的乱码问题都可以解决)
		 */
		response.setContentType("text/html;charset=utf-8");

		HttpServletRequest myRequest = new MyHttpServletRequest(req);
		//处理完后一定要放行过滤器, 才可以接着访问下面的资源
		chain.doFilter(myRequest, response);
	}
	
	/* 在Filter实例销毁之前立即执行
	 * 进行善后的处理
	 */
	public void destroy() {}
}

class MyHttpServletRequest extends HttpServletRequestWrapper{
	private boolean isEncode = true;
	/* isEncode 是否进行手动编解码的标识, 
	  默认值是true, 表示还没有手动编解码 */
	private HttpServletRequest request;
	public MyHttpServletRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	@Override
	public String getParameter(String name) {
		return this.getParameterValues(name) == null? null : this.getParameterValues(name)[0];
	}

@Override
public String[] getParameterValues(String name) {
	return this.getParameterMap().get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
	/*
	该方法可以返回所有请求参数组成的map集合, 此时map中
	保存的数据是乱码(get提交), 我们可以遍历map中的每一个
	参数值, 手动编解码处理完后将正确的数据再次存回map中,
	最后返回一个没有乱码的map集合
	 */
	if("POST".equalsIgnoreCase(request.getMethod())){//是POST提交
		return request.getParameterMap();
	}else if("GET".equalsIgnoreCase(request.getMethod())){
		//遍历map, 挨个取出乱码, 手动编解码再次存回map并返回map
		Map<String, String[]> map = request.getParameterMap();
		if(isEncode){
			for (Map.Entry<String, String[]> entry : map.entrySet()) {
				//取出每一个键值对, 由于值是数组, 还需要遍历
				String[] vs = entry.getValue();
				for (int i = 0; i < vs.length; i++) {
					try {
						vs[i] = new String(vs[i].getBytes("iso8859-1"), "utf-8");
					} catch (Exception e) {
						e.printStackTrace();
						throw new RuntimeException(e);
					}
				}
			}
			isEncode = false;
		}
		return map;
	}else{//其他5种提交方式
		return request.getParameterMap();
	}
}

}

下面提出配置文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<display-name></display-name>
	<!-- 配置全站乱码解决过滤器 -->
	<filter>
		<filter-name>EncodingFilter</filter-name>
		<filter-class>com.tedu.jt.filter.EncodingFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>EncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

猜你喜欢

转载自blog.csdn.net/weixin_42867325/article/details/82808726
今日推荐