动态代理解决网站字符集编码

1、首先看一个装饰模式解决字符集编码问题


  我们使用装饰者对request进行增强,从而使得get和post使用request.getParameter()获得的数据没有乱码:

  首先来一个Servlet,用于处理客户端请求:

package 装饰者模式解决乱码;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DataServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public DataServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获得数据
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		System.out.println("前:" +username+"@"+password);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获得数据
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		System.out.println("前:" +username+"@"+password);
	}
	
}


  创建HttpServletRequest的增强类,借助HttpServletRequestWrapper:

package 装饰者模式解决乱码;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;


/**
 *
 *  sun 提供 HttpServletRequest 接口使用装饰者编写默认类,及所有的方法都没有增强的。
 *  * 之后我们只需要继承即可
 *  
 *  增强response对象,提供使用装饰者设计模式编写默认类:HttpServletResponseWrapper
 */
public class MyRequest extends HttpServletRequestWrapper {
	//保持对接口的引用
	private HttpServletRequest request;
	//构造方法
	public MyRequest(HttpServletRequest request) {
		super(request);
		//赋值
		this.request = request;
	}
	//重写某个方法
	@Override
	public String getParameter(String name) {
		//首先获得参数,这是没有改变编码的值
		String value =  request.getParameter(name);
		//首先判断请求方式
		String method = request.getMethod();
		if ("GET".equals(method)) {
			try {
				value = new String(value.getBytes("ISO-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}else {
			try {
				request.setCharacterEncoding("utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return value;
	}

}


  在客户端向服务器发送请求时,我们需要对其进行拦截:

package 装饰者模式解决乱码;

import java.io.IOException;
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.HttpServletResponse;

public class EncodingFilter implements Filter {

    public EncodingFilter() {
    }

	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		//强转
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		//post编码
		response.setCharacterEncoding("UTF-8");
		//使用装饰者模式增强
		MyRequest myRequest = new MyRequest(request);
		//放行
		chain.doFilter(myRequest, response);
		System.out.println("我是中国人!");
		

			/*//0 强转
			HttpServletRequest request = (HttpServletRequest) req;
			HttpServletResponse response = (HttpServletResponse) resp;			
			//1 post乱码
			request.setCharacterEncoding("UTF-8");		
			//2 使用装饰者增强request
			MyRequest myRequest = new MyRequest(request);		
			chain.doFilter(myRequest, response);*/
			
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}

}

2、动态代理解决


  客户端页面:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>




动态代理解决get方式乱码问题


	
用户名:
密码:

  写一个Servlet:

package solveresponseencoding;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/DataServlet")
public class DataServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public DataServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获得请求参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//打印值
		System.out.println(request.getMethod() + " : " + username + " @ " + password);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}


  对请求进行拦截的过滤器:

package solveresponseencoding;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter("/*")
public class EncodingFilter implements Filter {

    public EncodingFilter() {
    }

	public void destroy() {
	}
	/*
	 * 本方法会拦截所有请求,在本方法中对request进行增强
	 */
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		//强转
		final HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		//解决post乱码
		request.setCharacterEncoding("utf-8");
		//创建动态代理对象
		HttpServletRequest myRequest = (HttpServletRequest) Proxy.newProxyInstance(
				EncodingFilter.class.getClassLoader(), 
				new Class[]{HttpServletRequest.class},
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						//如果是getParameter方法,获取参数
						if ("getParameter".equals(method.getName())) {
							String value = request.getParameter((String)args[0]);
							//System.out.println("value值为:"+value);
							//如果是get请求,就增强
							if ("GET".equalsIgnoreCase(request.getMethod())) {
								value = new String(value.getBytes("ISO-8859-1"), "utf-8");
								System.out.println("我是get方法:");
							}
							return value;
						}
						return method.invoke(request, args);
					}
				});
		chain.doFilter(myRequest, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
	}

}


  动态代理解决这个问题,将增强放到了过滤器中,不同之处他没有专门的增强类,而是通过动态代理技术在运行期间动态生成的,对于InvocationHandler接口采用了匿名内部类的方式。



动态代理解决网站字符集编码_第1张图片

你可能感兴趣的:(------【设计模式】,●,架构设计)