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

简介: 1、首先看一个装饰模式解决字符集编码问题   我们使用装饰者对request进行增强,从而使得get和post使用request.getParameter()获得的数据没有乱码:   首先来一个Servlet,用于处理客户端请求: package 装饰者模式解决乱码;import java.io.IOException;import javax.servlet.Serv

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"%>
<!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>动态代理解决get方式乱码问题</title>
</head>
<body>
	<form action="/proxy/DataServlet" method="get">
		用户名:<input type="text" name="username" value="胡根得" /><br/>
		密码:<input type="password" name=password value="就不告诉你"><br/>
		<input type="submit" value="提交get请求">
	</form>
</body>
</html>

  写一个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);
	}

}


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

<span style="font-size:18px;">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 {
	}

}
</span>


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




目录
相关文章
|
1月前
|
存储 Java API
动态代理实现的两种方式
【10月更文挑战第10天】
29 2
|
6月前
|
JSON 前端开发 Java
数据映射框架之三大神器:反射、注解、动态代理
数据映射框架之三大神器:反射、注解、动态代理
61 3
数据映射框架之三大神器:反射、注解、动态代理
|
Java 编译器 数据库连接
cglib动态代理 | 如何生成代理类、代理类内容解析
cglib动态代理 | 如何生成代理类、代理类内容解析
|
缓存 Java API
反射机制的深入解析
反射机制是Java语言中一项重要的特性,它允许程序在运行时动态地获取和操作类的信息。本文将从原理、应用场景以及性能方面来深入解析反射机制,帮助读者更好地理解和使用这一强大的功能。
75 1
|
Java
动态代理有哪些实现方式?
动态代理是一种在运行时创建代理对象的技术,它可以在不修改目标对象的情况下,通过代理对象来增强目标对象的功能。在Java中,有两种主要的动态代理实现方式:JDK动态代理和CGLIB动态代理。
151 0
|
Java
查看JDK动态代理生成的类的内容
首先我们先定义一个接口: public interface PersonInter { String test(String str); }接着就是我们想的要生成的JDK代理类源码的代码: public class JdkProxy...
1519 0
|
Java Spring
Java代理模式及动态代理详解
Java代理模式及动态代理详解
138 0
Java代理模式及动态代理详解
|
Java Spring
(十七)关于动态代理,你能说出动态代理的几种方式?
动态代理是指代理类不是写在代码中的,而是在代码运行过程中产生的,Java提供了两种方式来实现动态代理,分别是基于Jdk的动态代理和基于Cglib的动态代理。
|
安全 架构师 Java
Java中的原生动态代理和CGLIB动态代理的原理,我不信你全知道!
动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询、测试框架的后端mock、RPC,Java注解对象获取等。静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在编译期确定的。
|
Java Spring
Java代理模式以及动态代理的两种实现
Java代理模式 java静态代理模式 首先关于java的代理模式我的理解是:分为四个部分1 针对于客户端的部分2 有一个公共的接口3 有个被代理的类4 有个代理类而代理模式带来的优点是:我们可以对被代理类增加更多的处理,在Spring的AOP中就是使用的代理模式可以使得针对于切面进行编程。
1869 0