博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态代理解决网站字符集编码
阅读量:6589 次
发布时间:2019-06-24

本文共 6467 字,大约阅读时间需要 21 分钟。

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接口采用了匿名内部类的方式。

你可能感兴趣的文章
building xxx gradle project info的解决办法
查看>>
Vagrant (一) - 基本知识
查看>>
在 CentOS 7 上搭建 Jenkins + Maven + Git 持续集成环境
查看>>
数据结构与算法 | Leetcode 19. Remove Nth Node From End of List
查看>>
一起来读you don't know javascript(一)
查看>>
[LeetCode] 862. Shortest Subarray with Sum at Least K
查看>>
【分享】终端命令工具 自动生成vue组件文件以及修改router.js
查看>>
[LeetCode] Student Attendance Record I
查看>>
PHP回顾之多进程编程
查看>>
spring boot + redis
查看>>
Ajax技术细节
查看>>
nuxt.js部署vue应用到服务端过程
查看>>
删除数组中的指定元素 | JavaScript
查看>>
CSS3+JS实现静态圆形进度条【清晰、易懂】
查看>>
关于树形插件展示中数据结构转换的算法
查看>>
图片加载框架之Fresco
查看>>
Spotify开源其Cassandra编排工具cstar
查看>>
高性能web建站规则(将js放在页面底部)
查看>>
Java EnumMap工作原理及实现
查看>>
阐述Spring框架中Bean的生命周期?
查看>>