增强类实现通用字符集编码过滤器

  1. 需求分析
        需求:
            不管是get请求还是post请求,只要我们调用request.getParameter(name)方法获取参数值,就不要产生乱码。
        增强一个类中的方法有三种方式:
        1.继承:
            条件:必须要能够控制被增强类的构造方法
        2.装饰者模式:
            条件①:装饰者(增强的类)和被装饰者(被增强的类)都要实现同一个接口;
            条件②:装饰者(增强的类)要获得被装饰者的引用
            缺点:如果接口中的方法很多那么就要实现很多方法。
        3.动态代理:  后续spring框架
            同样也是基于接口实现的。
  2. 乱码产生原因分析
        get方式 乱码原因
            请求发送时会进行进行URL编码,编码格式为UTF-8
            服务器接收时使用ISO-8859-1解码,不支持中文,此时已经产生乱码
            手动调用request.getParameter(乱码)方法时,参数已经是乱码了
        解决方法
            将乱码使用ISO-8859-1编码,得到UTF-8编码后的数据
            再使用UTF-8解码得到原数据
        post方式乱码原因
            请求发送的数据在请求体中 
            request对象接收数据后将数据放入缓冲区
            缓冲区默认使用ISO-8859-1编码格式进行编码,不支持中文
            ISO-8859-1不支持中文
            手动调用request.getParameter()方法时,使用ISO-8859-1解码获得乱码
        解决方法
            将缓冲区编码格式设置为UTF-8,以UTF-8格式进行编码与解码
  3. 通用的字符集编码过滤器实现思路
        创建一个类继承HttpServletRequestWrapper
        这个类就是HttpServletRequest对象的增强类
        重写强HttpServletReques的getParameter()方法
        在过滤器的doFilter()方法里面将普通的request对象增强,并传递下去
      
         继承关系:
              public interface ServletRequest
              public interface HttpServletRequest extends ServletRequest
             public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest
        装饰者模式:
            1被增强的类和增强的类需要实现相同的接口。
                使增强类重与被增强类实现相同的方法
            2在增强的类中获得被增强的类的引用。
                用于增强类初始化
            3重写增强request.getParameter()方法
                实现增强功能
            理解:
                增强类就像是被增强类的哥哥,某些能力比弟弟强一些
            缺点:接口中的方法过多,重写很多其他的方法
  4. 代码实现

sub.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>get提交方式</h1>
<form action="${ pageContext.request.contextPath }/ServletDemo1" method="get">
	姓名:<input type="text" name="name"/><br>
	<input type="submit" value="提交">
</form>
<h1>post提交方式</h1>
<form action="${ pageContext.request.contextPath }/ServletDemo1" method="post">
	姓名:<input type="text" name="name"/><br>
	<input type="submit" value="提交">
</form>
</body>
</html>

GenericEncodingFilter

public class GenericEncodingFilter implements Filter {
	public void destroy() {
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request; 
		MyHttpServletRequest myReq = new MyHttpServletRequest(req);
		chain.doFilter(myReq, response);
	}
	public void init(FilterConfig fConfig) throws ServletException {
	}
}

ServletDemo1

public class ServletDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//此时实际调用的MyHttpServletRequest中重写的方法
		String parameter = request.getParameter("name");
		System.out.println(parameter);
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//此时实际调用的MyHttpServletRequest中重写的方法
		String parameter = request.getParameter("name");
		System.out.println(parameter);
	}

}

MyHttpServletRequest

/**
 *	自定义增强类-MyHttpServletRequest增强HttpServletReques的getParameter()方法
 * 
 * 
 *	继承关系:
 * 		public interface ServletRequest
 * 		public interface HttpServletRequest extends ServletRequest
 * 		public class HttpServletRequestWrapper extends ServletRequestWrapper implements HttpServletRequest
 *	装饰者模式:
 *		1被增强的类和增强的类需要实现相同的接口。
 *			使增强类重与被增强类实现相同的方法
 *	2在增强的类中获得被增强的类的引用。
 *			用于增强类初始化
 *		3重写增强request.getParameter()方法
 *			实现增强功能
 *		理解:
 *			增强类就像是被增强类的哥哥,某些能力比弟弟强一些
 *     	缺点:接口中的方法过多,重写很多其他的方法
 *  执行流程:
 *  	sub.jsp->GenericEncodingFilter->ServletDemo1
 *  	1.提交数据
 *  	2.过滤器创建增强类MyHttpServletRequest对象并将对象作为参数传递给Servlet
 *  	3.执行增强类MyHttpServletRequest对象中的增强重写的getParameter()方法
 */
//1被增强的类和增强的类需要实现相同的接口-HttpServletRequest
public class MyHttpServletRequest extends HttpServletRequestWrapper{
	private HttpServletRequest request;

	//2在增强的类中获得被增强的类的引用。
	public MyHttpServletRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	@Override
	//3重写增强request.getParameter()方法:
	public String getParameter(String name) {
		//判断请求方式
		if("POST".equalsIgnoreCase(request.getMethod())){
			// post方式的请求
			/*
			 post方式乱码原因
			 	请求发送的数据在请求体中 
			 	request对象接收数据后将数据放入缓冲区
			 	缓冲区默认使用ISO-8859-1编码格式进行编码,不支持中文
			 	ISO-8859-1不支持中文
			 	手动调用request.getParameter()方法时,使用ISO-8859-1解码获得乱码
			 解决方法
			 	将缓冲区编码格式设置为UTF-8,以UTF-8格式进行编码与解码
			 */
			try {
				request.setCharacterEncoding("UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else if("GET".equalsIgnoreCase(request.getMethod())){
			// get方式的请求
			/*
			get方式 乱码原因
			 	请求发送时会进行进行URL编码,编码格式为UTF-8
			 	服务器接收时使用ISO-8859-1解码,不支持中文,此时已经产生乱码
			 	手动调用request.getParameter(乱码)方法时,参数已经是乱码了
			 解决方法
			 	将乱码使用ISO-8859-1编码,得到UTF-8编码后的数据
			 	再使用UTF-8解码得到原数据
			 */
			String value = super.getParameter(name);
			try {
				//byte[] getBytes(Charset charset)  
				//使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组
				//String(byte[] bytes, String charsetName) 
		        //通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
				//先编码再解码
				value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return value;
		}
		return super.getParameter(name);
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值