代理(Proxy)_请叫我木丁西的博客-程序员宝宝

技术标签: Proxy  代理  javaSE  史上最全的JavaSE基础教程  

代理(Proxy)

      对指定接口的某一个方法进行功能扩展,可以使用代理

代理API

|--java.lang.reflect.Proxy

         static Object newProxyInstance(

  ClassLoader loader,    当前使用的类加载器

  Class<?>[] interfaces,   目标对象实现的接口类型

  InvocationHandler h    事件处理器:当执行上面接口中的方法的时候,就会自动触发事件处理器代码,把当前执行的方法(method)作为参数传入。

       )

案例:

①在处理http请求参数时,编码处理时过滤器的编写,为HttpServletRequest对象创建代理对象

package com.cn.filter;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 编码处理过滤器
 * @author liuzhiyong
 *
 */
public class EncodingFilter implements Filter{
	
	/**
	 * 过滤器业务处理方法:处理公用的业务逻辑操作
	 */
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		
		//转型
        //目标对象
		final HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)res;
		/**
		 * 1.处理公用的逻辑业务
		 */
		//设置post方式提交的请求的编码
		request.setCharacterEncoding("utf-8");//只对POST提交有效
		//设置页面打开时的编码格式,设置响应体的编码格式
		response.setContentType("text/html;charset=utf-8");
		
		/**
		 * 出现get中文乱码,是因为在request.getParameter("参数名")方法内部没有进行提交方式判断并处理
		 * 
		 * 解决:对指定接口的某一个方法进行功能扩展,可以使用代理:
		 * 		对request对象(目标对象),创建代理对象
		 */
		HttpServletRequest requestProxy =(HttpServletRequest)Proxy.newProxyInstance(
				request.getClass().getClassLoader(),// 定义代理对象类的类加载器。负责加载类的对象
				new Class[]{HttpServletRequest.class}, //代理类要实现的接口列表
				new InvocationHandler(){ 当调用目标对象对象方法的时候, 自动触发事务处理器
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)//这里的args是调用方法传入的参数
					throws Throwable {
				//定义方法返回值
				Object returnValue = null;
				
				//当前执行方法的方法名
				String methodName = method.getName();
				//判断:对getParameter方法进行GET方式提交中文处理
				if("getParameter".equals(methodName)){
					
					//获取请求数据的值
					String parameterValue = request.getParameter(args[0].toString());//调用目标对象的方法
					
					//获取提交请求的提交方式
					String submitMethod = request.getMethod();
					
					//判断,如果是GET提交,需要对数据进行处理(POST提交已经处理过了)
					if("GET".equals(submitMethod)){//注意在Servlet中这里是大写的GET
						if(parameterValue!=null && !"".equals(parameterValue.trim())){
							//处理GET方式提交的中文
							parameterValue = new String(parameterValue.getBytes("ISO-8859-1"), "UTF-8");
						}
					}
					return parameterValue;//返回getParameter方法的返回值
				}else{
					returnValue = method.invoke(request, args);//调用目标对象request的其它方法
					return returnValue;//返回返回值
				}
			}
		});
		
		
		//2.放行(进入下一个过滤器或者进入Servlet)
		chain.doFilter(requestProxy, response);//传入request代理对象requestProxy
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
}
②为Connection对象创


②为Connection对象创建代理对象

//原始的目标对象
final Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
/*****************对Connection对象代理***********************/
//对conn创建其代理对象。返回一个指定接口的代理类实例
Connection proxy = (Connection)Proxy.newProxyInstance(
	conn.getClass().getClassLoader(),// 定义代理类的类加载器。负责加载类的对象。
	new Class[]{Connection.class},//代理类要实现的接口列表
	new InvocationHandler(){// 当调用con对象方法的时候, 自动触发事务处理器
		@Override
		public Object invoke(Object proxy, Method method,
				Object[] args) throws Throwable {
			//方法返回
			Object result = null;
			// 当前执行的方法的方法名
			String methodName = method.getName();
			if("close".equals(methodName)){
				//连接放入连接池
				pool.add(conn);
			}else{
				result = method.invoke(conn, args); 调用目标对象的其它方法
			}
			return result;
		}
		
	}//指派方法调用的调用处理程序 
);


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/QQ1012421396/article/details/70433573

智能推荐

_stdcall与_cdecl的区别_机器视觉001的博客-程序员宝宝_stdcall与cdecl

_stdcall与_cdecl的区别  最大的区别就是__cdecl是由调用函数者释放堆栈,而__stdcall由被调用者释放。但是在调用任一种函数时,都没有进行显示的释放堆栈工作。这个工作由编译器完成,它帮我们生成了这个中间要使用的代码。在C语言中,假设我们有这样的一个函数:int function(int a,int b)调用时只要用result = function(1,2)...

SpringBoot使用Google guava缓存_He Yanbo的博客-程序员宝宝

Springboot使用Google guava缓存开发环境springbootguavadocker-client应用场景用来存储DockerClient的client连接,项目通过操作docker-client提供对docker的可视化界面操作,操作范围没有固定,可以是当前k8s集群上的任意节点,或者是任意主机的docker,所以只能根据接口传递的主机ip和docker....

android webkit案例,demo中webview独立进程例子在android10上崩溃,其他例子正常_weixin_39940688的博客-程序员宝宝

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.violetnight.violetnight/com.violetnight.violetnight.ui.activity.other.web.activity.RemoteWebViewActivity}: android.view.InflateEx...

【术】c#集合相关主题_zhou8jie的博客-程序员宝宝

https://msdn.microsoft.com/zh-cn/library/0ytkdh4s.aspx 系统把这一堆看了

java8中stream常用方法_泪伤~ 不离的博客-程序员宝宝

map: 用作类型转换 如把集合里面的字符串转为大写,或者一个对象的集合取几个字段转为新的对象集合filter: 过滤 符合条件的集合元素保存下来,不符合条件的去掉flatMap:合并集合,比如List Album里面有一LIst 对象,这个时候就能不通过循环的方式把 List 里的每一个元素的 trasks 对象组装成一个新的集合reduce: reduce可以做累加运算, .reduce(0, (a,b)-&gt; a+b);count: count和size一样返回的是元素的个数max,mi

(纪中)4754. 矩阵_。十二。的博客-程序员宝宝

解题思路我们把所有最小矩阵扔进堆里,每次取堆顶更新即可代码暴力#include&lt;iostream&gt;#include&lt;cstdio&gt;#include&lt;algorithm&gt;#include&lt;iomanip&gt;#include&lt;cstring&gt;#include&lt;cmath&gt;#include&lt;map&gt;#include&lt;queue&gt;#define ll long long#define ld...

随便推点

Flutter 软键盘遮挡问题:弹出时布局或Dialog上移_gnifeifeiing的博客-程序员宝宝

对于软件盘遮挡问题,首先考虑Scaffold作为根布局,背景色设为透明.Dialog的大概布局可以这样设计:Scaffold -&gt; Center -&gt; SingleChildScrollView -&gt; Column注意:dialog点击外部弹框消失,可以在Scafflod外部加一个GestureDetector:onTap: () { Navigator.of(context).pop();},...

[1020]hive中分区表的创建_周小董的博客-程序员宝宝_hive创建分区表

1、开启分区set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;否则会出抛出异常:2、创建分区表创建静态分区表:create table test_part_table(word string,num bigint )partitioned by(dt string)row format delimited fields terminated by '\t';

Spring集成消息队列RabbitMQ_小超写博客的博客-程序员宝宝

1. RabbitMQ简介1.1. RabbitMQRabbitMQ是由Erlang(爱立信公司)语言开发,实现Advanced Message Queuing Protocol (AMQP高级消息队列协议)的消息中间件。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。1.2. 结构图 • Broker:消息队列服务器实体,例如RabbitMQ服务 •

技术干货 | 基于 MindSpore 实现图像分割之平均表面距离_昇思MindSpore的博客-程序员宝宝_平均表面距离

顾名思义,Meansurfacedistance这个指标就是P中所有点的表面距离的平均。这个指标又可称为AverageSymmetricSurfaceDistance(ASSD),它也是医疗图像分割竞赛CHAOS中的一个评估指标。今天为大家带来的内容是Meansurfacedistance平均表面距离的原理介绍及MindSpore的实现代码。今天简单的讲解一下Meansurfacedistance平均表面距离。当我们评价图像分割的质量和模型表现时,经常会用到各类表面距离的计算。...

服务器 ---文章转载_KFidcRuly的博客-程序员宝宝

从广义上讲,服务器是指网络中能对其它机器提供某些服务的计算机系统(如果一个PC对外提供ftp服务,也可以叫服务器)。  从狭义上讲,服务器是专指某些高性能计算机,能通过网络,对外提供服务。相对于普通PC来说,在稳定性、安全性、性能等方面都要求更高,因此CPU、芯片组、内存、磁盘系统、网络等硬件和普通PC有所不同。服务器作为网络的节点,存储、处理网络上80%的数据、信息,因此也被称为网络的灵魂。...

推荐文章

热门文章

相关标签