使用AspectJ审计Spring MVC Webapp。 第2部分

现在,如果您有兴趣创建一个以Aspectj的@Aspect@Before批注的形式使用面向方面编程(AOP)的Spring MVC Webapp来审核用户对屏幕的访问,那么这是您想要阅读的博客。

正如我在上一个博客中所说的那样,审核用户对屏幕的访问是面向方面编程(AOP)很好解决的少数几个交叉问题之一。 就我的演示代码而言,其想法是,您将注释添加到适当的控制器,并且每次用户访问页面时,都会记录该访问。 使用此技术,您可以构建最流行的屏幕的图片,从而构建应用程序中最流行的功能块。 知道了这些细节之后,就可以更轻松地决定将开发目标放在何处,因为开发几乎没有人使用过的那些应用程序块是没有用的。

对于演示代码,我创建了一个简单的Spring MVC应用程序,该应用程序具有两个屏幕:主页和帮助页面。 在此之上,我创建了一个简单的批注: @Audit ,用于将控制器标记为需要审计的控制器(并非所有控制器都需要,尤其是如果您选择审计功能点而不是单个屏幕时),并且告诉建议对象的屏幕ID。 我已经在下面的代码片段中演示了这一点:

@Audit("Home") @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) {

在停留在AspectJ方面之前,首先要做的是使用为工作设计的Spring模板创建标准的Spring MVC Web应用程序:

下一步要做的就是对POM文件进行一堆更改,如我之前的博客中所述 。 这些并不是一切必不可少的,它们对于一切正常工作都是必不可少的。 但是,请确保您添加了aspectJwearver依赖项并删除了AspectJ插件定义。

该应用程序具有两个控制器和两个简单​​的JSP。 第一个控制器是从Spring MVC应用程序中获取的HomeController ,第二个控制器是旨在在应用程序的任何页面上显示帮助的HelpController 。 我在下面包括了HelpControllershowHelp(…)方法,但这只是为了完整性。 在这种情况下,只要有几个要审核的控制器实际上没有关系。

@Controller() 
public class HelpController { @Audit("Help")  // User has visited the help page @RequestMapping(value = "/help", method = RequestMethod.GET) public String showHelp(@RequestParam int pageId, Model model) { String help = getHelpPage(pageId); model.addAttribute("helpText", help); return "help"; }

从上面的代码中,您可以看到我的两个RequestMapping方法都使用@Audit注释进行了注释,因此下一步是其定义:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface Audit { String value(); 
}

此代码的关键是保留策略和目标。 保留策略必须设置为RetentionPolicy.RUNTIME ,这意味着编译器不会丢弃注释,并确保在运行时将注释保存在JVM中。 @Target定义可以在何处应用注释。 在这种情况下,我只希望将其应用于方法,因此目标是ElementType.METHOD 。 注释必须包含一个值,在这种情况下,该值用于保存用户当前正在访问的屏幕的名称。

下一个关键抽象是AuditAdvice类,如下所示:

@Aspect 
public class AuditAdvice { @Autowired private AuditService auditService; /** * Advice for auditing a user's visit to a page. The rule is that the Before annotation * applies to any method in any class in the com.captaindebug.audit.controller package * where the class name ends in 'Controller' and the method is annotated by @Audit. * * @param auditAnnotation *            Audit annotation holds the name of the screen we're auditing. */ @Before("execution(public String com.captaindebug.audit.controller.*Controller.*(..)) && @annotation(auditAnnotation) ") public void myBeforeLogger(Audit auditAnnotation) { auditService.audit(auditAnnotation.value()); } }

这有两个AspectJ注释: @Aspect@Before@Aspect批注将AuditAdvice类标记为一个方面 ,而@Before批注意味着定义与作为@Before批注的参数的表达式匹配的任何方法之前,将调用auditScreen(…)方法。

这种表达是很酷的想法。 我已经在Spring应用程序中使用AspectJ的@AfterThrowing建议中的博客中介绍了execution表达式的构造; 但是,总而言之,我将对所有具有公共可见性,返回String且位于com.captaindebug.audit.controller程序包中并且将单词Controller包含@Before方法都应用@Before注释方法。班级名称。 换句话说,我很难将此执行表达式应用于除我的应用程序的控制器以外的任何对象,并且这些控制器必须由@Audit注释进行注释,如@annotation(auditAnnotation)表达式和auditScreen(…)方法的Audit auditAnnotation参数。 这意味着我不能无意中将@Audit注释应用于除控制器之外的任何东西

AuditAdvice类将实际审核的职责委托给AuditService 。 这是一项虚拟服务,因此与其执行诸如将审核事件存储在数据库中之类的有用操作,不如将其简单地添加到日志文件中。

@Service 
public class AuditService { private static Logger logger = LoggerFactory.getLogger(AuditService.class); /** * Audit this screen against the current user name * * It's more useful to put this info into a database so that that you can count visits to * pages and figure out how often they're used. That way, you can focus your design on the * popular parts of your application. The logger is just for demo purposes. */ public void audit(String screenName) { String userName = getCurrentUser(); logger.info("Audit: {} - {}", userName, screenName); } /** * Get the current logged on user name by whatever mechanism available */ private String getCurrentUser() { return "Fred"; } }

因此,这就是本文所涵盖的代码,现在剩下要做的就是整理Spring配置文件,在这里没有太多要做。 首先,与任何AOP应用程序一样,您需要添加以下AOP启用行:

<aop:aspectj-autoproxy/>

…连同其架构详细信息:

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"

其次,您需要通过更新context:components-scan元素将建议类告知Spring上下文:

<context:component-scan base-package="com.captaindebug.audit"><context:include-filter type="aspectj"expression="com.captaindebug.audit.aspectj.AuditAdvice" /></context:component-scan>

您还可以选择从架构位置URI的末尾删除版本号。 例如:

http://www.springframework.org/schema/context/spring-context.3.0.xsd

变成:

http://www.springframework.org/schema/context/spring-context.xsd

这样做的原因是,由于没有任何版本号的架构URI似乎指向该架构的最新版本,因此它在将来的某个时刻简化了Spring版本的升级。

为了完整起见,我的配置文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --><!-- Enables the Spring MVC @Controller programming model --><annotation-driven /><!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --><resources mapping="/resources/**" location="/resources/" /><!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory --><beans:beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><beans:property name="prefix" value="/WEB-INF/views/" /><beans:property name="suffix" value=".jsp" /></beans:bean><aop:aspectj-autoproxy/><context:component-scan base-package="com.captaindebug.audit"><context:include-filter type="aspectj"expression="com.captaindebug.audit.aspectj.AuditAdvice" /></context:component-scan></beans:beans>

最后,当您运行该应用程序时,将记录用户对主页的访问。 当用户单击帮助链接时,也会记录对帮助页面的访问。 日志文件中的输出如下所示:

INFO : com.captaindebug.audit.service.AuditService - Audit: Fred - Home
INFO : com.captaindebug.audit.controller.HomeController - Welcome home! the client locale is en_US
INFO : com.captaindebug.audit.service.AuditService - Audit: Fred - Help

有关此代码和下一个博客的代码,请访问github: https : //github.com/roghughe/captaindebug/tree/master/audit-aspectj

参考: 使用AspectJ审计Spring MVC Webapp。 Captain Debug的Blog博客中的JCG合作伙伴 Roger Hughes的第2部分 。

翻译自: https://www.javacodegeeks.com/2013/07/auditing-a-spring-mvc-webapp-with-aspectj-part-2.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服装店管理系统打造门店拓客、促活、存留营销方案

打造门店拓客、促活和存留营销方案对于服装店的管理系统来说是非常重要的。以下是一些可行的方案&#xff1a; 1. 会员管理系统&#xff1a;引入会员管理功能&#xff0c;建立会员档案&#xff0c;跟踪会员消费记录和偏好。通过会员系统&#xff0c;可以实施积分制度、生日礼品…

mysql添加映射模块_iis7.5中让html与shtml一样支持include功能(添加模块映射)

刚开始弄得时候&#xff0c;发现了很多错误&#xff0c;其实很简单&#xff0c;参考shtm原来的设置就可以了前提条件&#xff1a;ServerSideIncludeModule的安装&#xff1a;在安装iis的时候选择上该服务(“在服务端包含文件”&#xff0c;选项)即可&#xff0c;如下&#xff1…

文件上传控件bootstrap-fileinput的使用

一、准备1、插件下载地址&#xff1a;https://github.com/kartik-v/bootstrap-fileinput/ 下载后的压缩包解压文件夹内容如下&#xff1a; js&#xff1a;插件核心js代码&#xff0c;引用fileinput.min.js/fileinput.js即可&#xff0c;默认插件语言为英文&#xff0c;如需要中…

在JPA 2.1中使用@Convert正确完成映射枚举

如果您曾经在JPA中使用过Java枚举&#xff0c;那么您肯定会意识到它们的局限性和陷阱。 使用enum作为Entity的属性通常是一个很好的选择&#xff0c;但是2.1之前的JPA不能很好地处理它们。 它给了您2 1个选择&#xff1a; 托肖夫达林 Enumerated(EnumType.ORDINAL) &#xf…

ssh架构之hibernate(一)简单使用hibernate完成CRUD

1.Hibernate简介 Hibernate是一个开放源代码的对象关系映射(ORM)框架&#xff0c;它对JDBC进行了非常轻量级的对象封装&#xff0c;它将POJO与数据库表建立映射关系&#xff0c;是一个全自动的orm框架&#xff0c;hibernate可以自动生成SQL语句&#xff0c;自动执行&#xff0c…

使用AspectJ审计Spring MVC Webapp。 第1部分

如果您像我一样&#xff0c;那么您将拥有那种编程天&#xff0c;一切似乎都进展顺利。 您编写代码和测试&#xff0c;它就可以正常工作。 然后还有其他日子&#xff0c;非常糟糕的日子&#xff0c;在那儿&#xff0c;您知道所编写的所有内容都尽可能正确&#xff0c;并且代码拒…

GitHub注册和Git安装

一、注册GitHub GitHub官方地址&#xff1a;https://github.com。 在浏览器中打开GitHub网址&#xff0c;通过首页进行注册&#xff0c;如下图所示。 二、安装Git Git官方下载地址&#xff1a;http://git-scm.com/download/。 Git支持多平台&#xff08;Mac OS X/Windows/Linux…

如何存储和恢复 HTML5 Canvas 状态

当我们在 HTML5 Canvas 上使用其 2D 上下文进行图形绘制的时候&#xff0c;可以通过操作 2D 上下文的属性来绘制不同风格的图形&#xff0c;例如不同字体、填充等等。 通常情况下&#xff0c;在画布上的绘图时&#xff0c;您需要更改在绘制的2D背景下的状态。例如&#xff0c;你…

innodb和my查询速度_吃透MySQL:MyISAM和InnoDB存储引擎详细介绍

一&#xff0c;MySQL基本架构MySQL基础架构可以分为两大类&#xff1a;Server层和存储引擎层。Server层&#xff1a; Server层涵盖了MySQL大部分核心业务功能&#xff0c;并且所有存储引擎的功能都在这一层实现。存储引擎层&#xff1a;存储引擎有很多&#xff0c;各自有着各自…

Java EE EJB拦截器教程和示例

在此示例中&#xff0c;我们将看到如何在EJB中使用拦截器并使用简单的Web应用程序对其进行测试。 1.简介 顾名思义&#xff0c;当您想拦截对EJB方法的调用时&#xff0c;将使用拦截器。 如果为Bean声明一个拦截器&#xff0c;则每次调用该Bean的方法时&#xff0c;该拦截器的一…

Mac python Tesseract 验证码识别

Tesseract 简介 Tesseract(/tesərkt/) 这个词的意思是"超立方体"&#xff0c;指的是几何学里的四维标准方体&#xff0c;又称"正八胞体"。不过这里要讲的&#xff0c;是一款以其命名的开源 OCR(Optical Character Recognition, 光学字符识别) 软件。 所谓…

如何判断html页面停止滚动?

写在开始的话 查遍的文献&#xff0c;没有找到js或者jquery定义好的方法可用&#xff0c;最后迫不得已自己写了个方法。&#xff08;如果哪位同学知道有其他方法&#xff0c;欢迎讨论&#xff09; 代码 var count_index 0;$(window).scroll(function(e) {if(count_index 0) {…

php 打乱数组顺序_PHP实现大转盘抽奖算法

php中文网最新课程每日17点准时技术干货分享本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法&#xff0c;希望对大家学习PHP抽奖有所帮助。流程&#xff1a;1.拼装奖项数组&#xff1b;2.计算概率&#xff1b;3.返回中奖情况。代码如下&#xff1a;中奖概率 v 可以…

linux线程基础篇----线程同步与互斥

linux线程基础----线程同步与互斥 一、同步的概念 1.同步概念 所谓同步&#xff0c;即同时起步&#xff0c;协调一致。不同的对象&#xff0c;对“同步”的理解方式略有不同。如&#xff0c;设备同步&#xff0c;是指在两个设备 之间规定一个共同的时间参考&#xff1b;数据库同…

分布式系统开发注意事项

开发分布式软件系统时&#xff0c;要考虑许多因素。 如果您甚至不知道第一句话中我在说什么&#xff0c;那么让我为您提供一些见解&#xff0c;示例以及有关分布式系统的实例。 总览 分布式系统是指多个物理硬件设备与单独的离散用户交互并通过这些硬件设备协作以为这些离散的…

只需5步,轻松创建HTML5离线应用

1 – 添加 HTML5 doctype第一件要做的事情是创建一个符合规范的 HTML5 文档。HTML5 doctype 相比于 xhtml 版本的 doctype 而言&#xff0c;要简单明了得多&#xff1a; <!DOCTYPE html><html> ...创建一个名为 index.html 的文档&#xff0c;或者猛击这里下载这份…

Java EE 7发布–反馈和新闻报道

Java EE 7已经存在了几天。 我们所有人都有机会观看直播活动或可用的重播 。 最后的MR版本完成了将他们的工作推向JCP的过程&#xff0c;基本上是一个总结。 是时候反思发生的事情以及我对此的想法了。 启动活动中的社区参与 这不是一个大秘密。 即使Oracle的Java EE 7发行可以…

HTML5中的本地数据库-Web SQL Database

html5增加新的特性&#xff0c;那就是增加了本地存储&#xff01;改善用户体验&#xff0c;或许html5会带着我们走进新的互联网时代。 下面看看怎样操作web 数据库吧&#xff01;&#xff01;首先新建数据库&#xff01; var db window.openDatabase("mydata", &quo…

解决swiper-slide在ion-slide-box不滑动的问题(暂且这么描述)

1&#xff0c;开发环境ionic1angularjs1 嗯对的版本都是最低版本 页面结构想要完成的功能是这样的&#xff08;比较丑 &#xff0c;不接受批评&#xff0c;捂脸&#xff09; 大致如图 代码结构&#xff1a; <ion-slide-box><ion-slide> //列表 <div class"…

Win10 系统直接在目录下打开cmd

每次用cmd命令&#xff0c;就要定位到当前文件夹&#xff0c;很麻烦&#xff0c;于是想了下&#xff0c;可不可以直接定位到要操作的文件夹&#xff0c;百度了一下&#xff0c;果然&#xff0c;度娘没有让我失望&#xff0c; 美滋滋的试了下。真的可以。在此记录下&#xff0c;…