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

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

时间: 2025-01-31 02:13:44

动态代理解决网站字符集编码的相关文章

使用动态代理解决Hibernate序列化,避免延迟加载问题

在使用Ajax: Hibernate Entity => json, Flex RemoteObject: Hibernate Entity => ActionScript Object的过程,经常碰到如下问题: 问题: 1.Hibernate碰到延迟加载的属性访问时如果session被关闭则抛出 LazyInitializationException 2.Hibernate中的one-to-many等关联关系在序列化时如果没有控制,则将整个 数据库都有可能被全部序列化 3.过多的使用DTO/

动态代理DynamicProxy 介绍

我们使用动态代理,主要是因为动态代理拥有这样的能力--使得某个类型A在运行的时候能转化为一个指定的接口I,即使这个类型A在定义的时候并没有从这个指定的接口I继承.这句话是什么意思了?还是回到当泛型的参数类型是动态的... 一文中的那个例子,在例子中,List<>并没有从ISimpleList继承,但是从表面看来,在运行的时候,我们通过动态代理可以以ISimpleList接口来"引用"List<>类型的对象. 动态代理是在运行时在内存中构建的一种类型,该类型实现了

JAVA核心层--反射--动态代理

本文发表于2010年,时间较早,部分问题解释不是十分准确,所以需要进一步了解,请参看2012年版本: java之架构基础-动态代理&cglib 要在JAVA技术上突破普通的层面,并拥有一翻设计理念的高度,除了要有很好的设计思维之外,反射在适当的使用下,将会把框架做得非常清晰,并且代码编写也非常简便. 在面向对象的编程中,我们为什么要忌讳去大量使用if else switch语句,因为这样写是将逻辑硬编码了,JAVA的思想就是将其配置化,一旦可配置化后,就逐渐可管理化,并随着产品的成熟逐步实现自动

【SSH系列】静态代理&amp;amp;&amp;amp;动态代理

从设计模式说起 代理模式是二十三中设计模式中的一种,代理模式就是指由一个代理主题来操作真实的主题,真实的主题执行具体的业务操作,而代理主题负责其她相关业务,简而言之,代理模式可以由以下三个部分组成: a.抽象角色:通过接口或抽象类声明真实角色实现的业务方法. b.代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. c.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用.第一次接触代理模式的是在学习大话设计模式的时候,首先

Windows资源浏览器——动态代理(java)

      写这篇博客是为了解决<Dota兄订餐--静态代理(java)> 里最终的遗留问题.       想必大家都或多或少了解一些Dos命令,在调用外部程序时,经常会用到dos命令来完成.其中有一条万能的命令,就是用Explorer.exe来打开任意程序,就相当于直接双击该程序.        先给大家看一下我们要调用的外部资源,放到一个文件夹中,包括图片.音乐.视频.文本文档.word文档.还有其他文档,最后还会加上一个网址.        我把Dos命令写入到一个bat中,也放入同一个

跟屌丝大哥学习设计模式---代理模式之动态代理

动态代理 java中动态代理机制的引入使得代理模式的思想更加完善与进步,它允许动态的创建代理并支持对动态的对所代理的方法进行调用.Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:  (1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args).在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上

乱码-postgresql字符集编码如何修改成utf_8??

问题描述 postgresql字符集编码如何修改成utf_8?? 2C 如题所说,现在我在JAVA插入一条语句,在数据库查询却变成了中文乱码,希望有人能够帮忙解决,谢谢! 解决方案 oracle 修改数据库的字符集编码为UTF-8oracle 修改数据库的字符集编码为UTF-8ORACLE修改数据库的字符集编码为UTF-8方法 解决方案二: http://blog.csdn.net/beiigang/article/details/7051605

java之架构基础-动态代理&amp;amp;cglib

本文核心主要参数动态代理和cglib: 在以前的文章中,有提及到动态代理,它要解决的就是,当我们的某些代码前面或后面都需要一些处理的时候,如写日志.事务控制.做agent.自动化代码跟踪等,此时会给你带来无限的方便,这是JVM级别的提供的一种代理机制,不过在这种机制下调用方法在JVM7出来前还没有invokeDynamic的时候,调用的效率是很低的,此时方法调用都是通过method的invoke去实现. 其基本原理是基于实现JVM提供的一个: InvocationHandler的接口,实现一个方

Java动态代理、cglib动态代理

说动态代理,需要先清楚静态代理.所谓静态代理就是程序员提前实现好的代理类,编译后class文件是已经存在的. 实现原理,利用Java代理模式,由一个代理类持有委托类的实例,并实现委托类一样的接口,来实现增强方法的目的. 我们主要用它来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情,甚至根本不去执行这个方法.因为在InvocationHandler的invoke方法中,你可以直接获取正在调用方法对应的Method对象.比如可以添加调用日志,做事务控制,对