动态代理在WEB与JDBC开发中的应用(WEB篇)

Java领域Web开发:Spring框架的实战应用 本文旨在为Java开发者提供Spring框架的全面指南,从基础概念到高级应用,覆盖Spring生态系统中最常用的组件和技术。我们将重点放在实际开发中的最佳实践和常见问题的解决方案上。文章首先介绍Spring框架的基本概念和核心组件,然后深入各个模块的实现原理,接着通过实际项目展示Spring的应用,最后讨论高级主题和未来发展趋势。: 控制反转,Spring框架的核心思想,将对象的创建和管理交给容器: 依赖注入,IoC的具体实现方式: 面向切面编程,用于处理横切关注点Bean。 阅读详情

WEB案例

目前有一个2005年开始,基于Struts1的Web项目A,其验证部分依赖于主站的SSO(单点登录)。在请求站点A的时候,用户会被强制带去做SSO验证,通过身份验证后后,主站会自动地把请求转发至A站点,并在request header中添加了用于保存登录用户ID的新属性SM_USER,然后A站点根据用户ID提供相应的服务。由于该项目是一个既存项目,所以其中残余大量像下面一样的测试代码。

String user_id = request.getHeader("XX_USER");
if (user_id == null) {
    user_id = "my_hard_coded_user_id";
}
UserProfile userProfile = new BizDao().getUserProfile(user_id);

其根本原因是在本地测试的时候无法于生产环境的SSO对接,只有把代码提交至公共的DEV服务器、UAT服务器或PROD服务器后,才能享受SSO为A站所提供的XX_USER数据,所以程序员在无法取得header数据的情况下,直接简单粗暴地对本地环境进行了硬编码处理。在只有几个人的小团队,这样的处理可能看起来也无所谓,但长年下来经手的人数也相当可观了,很多人都习惯使用自己的ID做测试,所以在SVN的历史版本中,硬编码的ID从A改到B、改到C、改到D……

问题分析

每个人都根据自己的喜好选择了使用自己的ID或是他人的ID,那么是否有一种办法可以统一接口一劳永逸呢?可能最容易想到的就是HttpServletRequest.setHeader,可惜HttpServletRequest并没有这样的API,为啥?个人猜测可能是因为request源于客户端,服务器端应该保持请求的原始性、纯净性和无毒性吧,而HttpServletResponse(http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html)则是在应用程序的控制之下,所以程序员可以对其任意践踏,setHeader、addHeader以及getHeader、getHeaders、getHeaderNames。既然没有API可用,直接进行包装代理吧,在Google的帮助下我们可以找到现成的方案来对request中的header进行重新定制,重点是HttpServletRequestWrapper类的实现。

http://vangjee.wordpress.com/2009/02/25/how-to-modify-request-headers-in-a-j2ee-web-application/

其实这个方案是在我实现动态代理方案之后找到的,两者思路几乎是一样的,都是对原始request进行包装代理,重新实现getHeader方法。

解决方案

不废话,直接上代码!

private static class RequestInvocationHandler implements InvocationHandler {
    private HttpServletRequest wrappedRequest;
    public RequestInvocationHandler(HttpServletRequest r) {
        wrappedRequest = r;
    }
    public static String dummyData = "my_hard_coded_id";
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("getHeader".equals(method.getName()) && args.length == 1 && "SM_USER".equals(args[0])) {
        	return dummyData;
        }
        return method.invoke(wrappedRequest, args);
    }
    public static HttpServletRequest createRequestWapper(HttpServletRequest r) {
    	if (null != r.getParameter("u")) {
    		dummyData = r.getParameter("u");
    	}
        return (HttpServletRequest)(Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),
            new Class[] {HttpServletRequest.class},
                new RequestInvocationHandler(r)));
    }
}

上面代码实现了对Request对象的代理,所有针对Request对象的调用都需经过invoke方法。在invoke方法中,我们可以针对不同的方法签名进行更为细粒度的控制。比如在WEB案例中提到的问题,可以专门针对getHeader方法进行重新定制,本来Request Header中并无该数据,但我们可以硬生生地“造”出数据。另外除了可以“造”出测试数据外,还可以通过请求中携带的参数“u”动态地进行数据修改,这样就实现了用户切换的功能。

既然代理类的问题解决了,下面该谈谈应在何时何地植入代理对象了。何时何地可以理解为切入时机,其实最初的是在org.apache.struts.action.RequestProcessor中植入代理对象的,但是在使用过程中发现该实现有一个弊端,那就是在非Struts请求时无法使用代理对象,比如直接访问JSP文件或是其它Servlet所提供的服务路径。这时自然而然地想到Filter,而使用Filter也是一痛,加入一个全新的Filter吧,有点破坏的整体设计的感觉,而放入其它Filter之中的话,看起来又不伦不类。但好歹是测试用,这两个方案可以折衷选择其一,具体实现如下。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
	request = RequestInvocationHandler.createRequestWapper((HttpServletRequest)request);
	chain.doFilter(request, response);
}

整体工作流程如下,用户首先发出请求,然后request对象在filter中被替换成代理对象,替换后的request被传入doFilter方法,之后不论是Servlet、Struts还是JSP,它们用到的都是我们定制的Request对象。

           +---------+         +---------+
           |         |         |         |
 Request   |         | +-----> | Servlet |
+--------> |  Filter |         |         |
           | +----+  |         |  Struts |
           | Request |         |         |
 Response  |      is |         |         |
<--------+ | wrapped |         |         |
           |    here | <-----+ |         |
           |         |         |         |
           +---------+         +---------+

后记

当然,如果想要修改request对象不止这一种方法,比如正统的方式是定义一个HttpServletRequestWrapper来重新定义request,具体案例请参考http://vangjee.wordpress.com/2009/02/25/how-to-modify-request-headers-in-a-j2ee-web-application/

【Java WEB】JDBC详解 JDBC JDBC(Java DataBase Connectivity java数据库连接) 是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的 本质:其实就是Java官方提供的一套规范(接口)。用于帮助开发人员快速实现不同关系型数据库的连接 快速入门 导入jar包 注册驱动 获取数据库连接 获取执行者对象 执行sql语句并返回结果 处理结果 释放资源 package study.jdbc; import java.s 阅读详情

相关推荐

Java Web从入门到实战

Java Web从入门到实战,十万+字符,一文带你从零到实战,内含Linux、Tomcat、Servlet、JSP、Mysql、JDBC、Mybatis、js、jQuery等超多内容

HelloCode 3万+

【Spring】AOP动态代理(jdk cglib)详解 底层原理及操作术语 五种通知类型(使用AspectJ 注解及XML操作)

进来学两招呀~

Le vent se lève, il faut tenter de vivre 1728

MyBatis通过 JDBC连接 SQL server 数据库简单例子,进阶使用动态代理

MyBatis通过 JDBC连接 SQL server 数据库简单例子,进阶,使用动态代理从xml生成mapper接口的实现

JDBC介绍及入门实例和对Proxy的介绍

JDBC 是一种 操作 数据库的 标准 和 规范 、只有标准 而没有具体的实现。

latherou的博客 403

从永恒之蓝看内网安全:企业如何用Nmap+MSF快速检测445端口风险

本文探讨了企业如何利用Nmap和Metasploit快速检测445端口风险,防范永恒之蓝(MS17-010)漏洞攻击。通过分阶段检测流程和自动化工具组合,企业可高效识别内网风险主机,并实施紧急隔离与长效防护策略,提升整体网络安全防护能力。

weixin_30772105的博客 601

保姆级教程:不用看古早代码,5分钟搞懂泛微ecology9附件存储与接口调用

本文详细解析了泛微ecology9附件存储与接口调用的核心原理,提供从基础概念到实战操作的完整指南。通过拆解文档化附件设计理念、解析RESTful接口参数,并给出Python代码示例,帮助开发者快速掌握附件上传与业务集成的关键技巧,提升二次开发效率。

weixin_28688385的博客 351

JDBC实战(六)数据源、连接池、代理模式、动态代理

文章目录连接池、代理模式、动态代理1、数据源和连接池1、创建基本的数据源类2、使用代理模式来保持因使用数据源连接池导致的用户关闭不习惯问题3、使用动态代理完善连接代理3.1、什么是动态代理3.2、使用动态代理来实现Proxy_MyConnection类 连接池、代理模式、动态代理 1、数据源和连接池 所谓数据源也就是数据的来源。它存储了所有建立数据库连接需要的信息。算是对数据库的一个抽象映射,即一个数据源对于一个数据库。 数据源有以下属性 databaseName String数据库名称,即数据库的SID

LH is programming hard 1265

CCC数字钥匙Release 3实战:如何用BLE/UWB实现无钥匙进入(附避坑指南)

本文深入解析CCC数字钥匙Release 3标准下BLE/UWB无钥匙进入系统的开发实践,涵盖硬件选型、安全测距协议、时序同步等关键环节,并提供实战调试技巧与安全攻防案例。特别针对BLE芯片配置、UWB模块选型等常见陷阱给出解决方案,帮助开发者高效实现厘米级精度的数字钥匙系统。

weixin_29326909的博客 256

数据库概述 5-连接池

内容介绍 1 preparedStatement 预编译对象 2 数据库的连接池 3 动态代理 模拟用户登录功能 需求: 我们在控制台输入用户名和密码,输入完用户名和密码后,获取输入的值,使用jdbc操作数据库,完成登录功能. 找到了:登录成功 找不到:用户名或密码错误 技术分析: jdbc 代码实现: 创建用户表: create table user ( ...

AdamCafe的博客 503

破译丰田BEAN总线之谜

我对CAN的深入了解并不是从CAN本身开始的,而是起源于丰田公司自主研发的BEAN总线。由于BEAN总线协议并不是公开的,而是一种技术机密,所以当丰田车不在使用BEAN总线两年多后的今天,虽然这里还不敢公开技术细节,但回想起当年的作品,随便写写也算对自己的努力有所交代。   南方都市报惠州版曾经报道过一则新闻,说的是丰田皇冠车被盗率非常高。其实两年前就已经知道了皇冠车的防盗系数很低,所以当时的首

粤嵌 5266

整理并记录几种运算放大器

运算放大器是一种十分常见的电子元器件,最近我在学习运放,以前在学校没有好好的学习,今天在B站看了唐老师讲运算放大器-唐老师讲电赛系列视频教程,记录下所学的,纯当是自己的笔记 学习运放,有两个重要的概念及重要的计算法宝,虚短vp=vn;和虚断ip=in 1反向比例运算电路 Rf可以大于、小于或等于R,起到放大、跟随、衰减输入的作用; 平衡电阻没有太高的精度要求,可加可不加; 有些运放内部集成了补偿电路,就不需要使用平衡电阻,加了反而增大误差,如OPA227 2.同向比例运放电路 .

qq_36823004的博客 6365

JDBC动态代理和CGLIB动态代理的意义

JDK 动态代理必须有接口轻量级,反射调用Spring AOP 默认首选CGLIB 代理不需要接口通过生成子类实现代理可以代理普通类,但 final 类或 final 方法不能代理适合没有接口的类Spring 的选择有接口:JDK 动态代理没接口:CGLIB 代理💡 小技巧:如果接口较多、代理方法不多,JDK 动态代理即可;如果目标类没有接口或者第三方库类需要代理,则用 CGLIB。代理(Proxy)在编程里,不仅是技术实现,更是一种设计模式思想。它的意义可以从。

weixin_44547668的博客 626

保姆级教程:手把手配置AutoSar诊断复位(Dcm 0x11服务联动BswM/EcuM)

本文提供AutoSar诊断复位(Dcm 0x11服务联动BswM/EcuM)的保姆级配置教程,详细讲解从诊断服务基础配置到BswM规则引擎搭建、服务端口映射及EcuM复位执行的完整流程。通过Vector配置工具的实际截图和代码片段,帮助开发者高效实现远程复位功能,并分享调试技巧与性能优化实践。

weixin_30756499的博客 544

动态代理在WEB与JDBC开发中的应用(JDBC篇)

动态代理在WEB与JDBC开发中的应用(JDBC篇)

KNIGHTRCOM(rcom10002的专栏) 2038

【WRF-Chem教程-附录 C】闪电-NOx 参数化方案详解

闪电-NOx 参数化方案详解

WW、forever的博客 974

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

动态代理在WEB与JDBC开发中的应用

WEB案例 目前有一个2005年开始,基于Struts1的Web项目A,其验证部分依赖于主站的SSO(单点登录)。在请求站点A的时候,用户会被强制带去做SSO验证,通过身份验证后后,主站会自动地把请求转发至A站点,并在request header中添加了用于保存登录用户ID的新属性SM_USER,然后A站点根据用户ID提供相应的服务。由于该项目是一个既存项目,所以其中残余大量像下面一样的测试代码...

weixin_30396699的博客 78

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

javaEE回顾之MyBatis以及封装工具类(动态代理、sqlSession、UUID)和web应用

使用MyBatis实现第一个web应用 主要目标: 在web项目当中使用mybatis 1、创建一个web project,我这里使用的servlet版本号是servlet 3.1, 在servlet 3.0版本之后,web.xml文件就可以不写了,所有的配置均采用注解 来完成。 2、eclipse部署项目的时候,关于项目的名称: settings目录下的:org.eclipse.wst.common.component <?xml version="1.0" encoding="UTF-

qq_30347133的博客 768

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

反射常见面试题

什么是反射? 反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。 哪里用到反射机制? 1.JDBC中,利用反射动态加载了数据库驱动程序。 2.Web服务器中利用反射调用了Sevlet的服务方法。 3.Eclispe等开发工具利用反射动态刨析对象的类...

qq_39565307的博客 8335

小白新手web开发简单总结(十八)-阶段总结

翻看这段时间的笔记,发现已经有16篇笔记了。 小白新手web开发简单总结(一)-什么是Tomcat 小白新手web开发简单总结(二)-什么是web.xml 小白新手web开发简单总结(三)-一个简单的Web开发项目 小白新手web开发简单总结(四)-web应用开发中的MVC 小白新手web开发简单总结(五)-JSP页面的四元素 小白新手web开发简单总结(六)-Spring的IoC容器 小白新手web开发简单总结(七)-数据库HSQLDB 小白新手web开发简单总结(八)-数据库HSQLDB

nihaomabmt的专栏 323

Java EE 企业级应用开发教程 第2版

基于 Servlet API 构建的原始 Web 框架作用于三层架构的表现层控制器接收客户端的请求对请求进行解析和封装将请求交给业务层处理视图对处理结果进行渲染响应给客户端工作原理组件处理器映射器处理器适配器视图解析器ORM 框架工作原理。

qq_35414977的博客 6183

Web day06 JDBC & Mybatis

客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用)客户端执行SQL语句:要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行后又需要关闭连接对象从而释放资源,每次执行SQL时都需要创建连接、销毁链接,这种频繁的重复创建销毁的过程是比较耗费计算机的性能。框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。

moskidi的博客 901

Java编程JDK动态代理概述与实战演示

Java JDK动态代理实例,展示了如何利用JDK提供的动态代理机制为已有接口实现添加额外行为(如日志记录、权限检查、缓存等)。 在这个例子中,LogInvocationHandler添加了方法调用的前后日志记录功能。当通过代理对象调用add()方法时,实际上会触发invoke()方法,在执行目标方法之前打印方法调用信息,执行之后记录方法执行耗时。

勤于笔记,成于点滴。 1132

JAVA常用特性:静态代理与动态代理

目录 代理: JDBC静态代理: JDBC动态代理: CGLIB字节码增强: 代理: 简单来说,代理就是原有业务不变的情况下,将一些额外的需求(方法的功能增强)交给别人来做。具体方式有两种:一种是静态代理(装饰者模式),一种是动态代理。 JDBC静态代理的原理:是通过纵向继承的方式,经过进一步的方法重写得到功能的增强。但由于类的单继承局限性,使得通过直接继承父类的方式来进行代理增强的...

AI_drag0n的博客 327
上一篇: VBA清除Excel密码保护,2003/2007/2010均适用
下一篇: 动态代理在WEB与JDBC开发中的应用(JDBC篇)
rcom10002
博客等级 码龄24年 117粉丝 93原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值