如果您像我一样,那么您将拥有那种编程天,一切似乎都进展顺利。 您编写代码和测试,它就可以正常工作。 然后还有其他日子,非常糟糕的日子,在那儿,您知道所编写的所有内容都尽可能正确,并且代码拒绝运行:显然有些错误,但是您不知道什么。 在为该博客编写代码时,我经历了其中一种日子。 这个想法是为了演示如何使用Spring和Aspectj来审核用户对屏幕的访问。
审核面向用户的屏幕访问是面向方面编程(AOP)很好解决的少数交叉问题之一。 就我的演示代码而言,其想法是,您将注释添加到适当的控制器,并且每次用户访问页面时,都会记录该访问。 使用此技术,您可以构建最流行的屏幕的图片,从而构建应用程序中最流行的功能块。 知道了这些细节之后,就可以更轻松地决定将开发目标放在何处,因为开发几乎没有人使用过的那些应用程序块是没有用的。
在下面的博客中,我之前已经讨论过AspectJ和AOP,因为它们展示了基础知识,但是很棒,但是它们并不是真正的Spring MVC应用程序。 我以前的博客是:
- AOP和AspectJ术语
- 定义Spring的AspectJ建议类型
- 在Spring应用程序中使用AspectJ的@After建议
- 使用Spring的AspectJ支持和@Before批注
- 在Spring应用程序中使用AspectJ的@AfterThrowing建议
这次我以为我会提出一个功能全面的Spring MVC应用程序,它使用了一个有用的AOP跨领域关注点。
对于演示代码,我创建了一个简单的Spring MVC应用程序,该应用程序具有两个屏幕:主页和帮助页面。 在此之上,我创建了一个简单的批注: @Audit
,用于将控制器标记为需要审计的控制器(并非所有控制器都需要,尤其是如果您选择审计功能点而不是单个屏幕时),并且告诉建议对象的屏幕ID,如以下代码段所示:
@Audit("Home") @RequestMapping(value = "/", method = RequestMethod.GET) public String home(Locale locale, Model model) {
也就是说,直到一切都变成梨形...
攻击的计划是编写我的简单@Audit
批注,并使用一个简单的AuditAdvice
类处理该批注,该类具有用Aspectj的@Before
批注进行批注的方法。 然后,我假装这是一个真正的建议类,这意味着将实际的审计委托给自动连接的AuditService
对象。
我首先使用Spring项目模板创建一个示例Spring MVC应用程序:
然后,我将所有代码放在一起,并希望它能正常工作,除非它不能工作:无论我尝试了什么,Spring都不AuditService
自动装配到AuditAdvice
类中。 这意味着当我的@Before
注释方法被调用时,它引发了NullPointerException
当您强烈怀疑自己的代码正确并且无法正常工作时,需要调查的领域之一就是项目POM文件和设置。
事实是,当您使用别人的API,项目设置或其他工具时,您倾向于信任它的程度超过信任自己的代码的程度。 我猜这是因为它通常是由一个非常受人尊敬的组织编写的,这使您觉得他们有一些神奇的方式来编写非常好的代码,而且它通常包含一堆您没有的东西真的很明白
由于API,工具,配置文件等都是由像您和我这样的程序员编写的,他们可能会犯与我们一样多的错误,所以这确实是不合理的。
每当我登上飞机时,这个事实通常都会让我感到担心,因为您不想发生30,000英尺的软件错误。
Spring MVC项目POM的问题在于,它已经过时并且充满了标准的Spring MVC Java应用程序所不需要的东西,此外,没有任何插件文档的链接,因此请查找所有内容和不同的设置意味着什么很难。
前一段时间,我确实写了一个名为Dissecting Spring的MVC Project POM的博客,试图解释Spring MVC模板应用程序POM的工作方式。
这些是我必须对标准Spring MVC模板POM文件进行的更改,才能使我的代码正常工作。
- 将项目使用的Spring版本更新为最新版本:3.2.3.RELEASE
- 将AspectJ的版本更新为1.7.1
- 删除Spring Roo版本号。
这将创建创建以下版本属性:
<org.springframework-version>3.2.3.RELEASE</org.springframework-version> <org.aspectj-version>1.7.1</org.aspectj-version>
- 删除其他Spring Roo依赖项:
<!-- Roo dependencies --> <dependency><groupId>org.springframework.roo</groupId><artifactId>org.springframework.roo.annotations</artifactId><version>${org.springframework.roo-version}</version><scope>provided</scope> </dependency>
这不是Roo项目,我讨厌不必要的配置。
- 删除对Spring存储库的引用:
<repositories><!-- For testing against latest Spring snapshots --><repository><id>org.springframework.maven.snapshot</id><name>Spring Maven Snapshot Repository</name><url>http://maven.springframework.org/snapshot</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><!-- For developing against latest Spring milestones --><repository><id>org.springframework.maven.milestone</id><name>Spring Maven Milestone Repository</name><url>http://maven.springframework.org/milestone</url><snapshots><enabled>false</enabled></snapshots></repository> </repositories>
- 本示例使用默认的WAR文件名,因此删除对maven-war-plugin的引用:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><configuration><warName>abc</warName></configuration> </plugin>
- 更新Surefire插件以删除Roo参考:
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><junitArtifactName>junit:junit</junitArtifactName><!-- Remove the excludes --><excludes><exclude>**/*_Roo_*</exclude></excludes></configuration> </plugin>
- 添加
aspectjweaver
如下依赖aspectjrt
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${org.aspectj-version}</version> </dependency>
- 删除AspectJ插件参考:
<plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><!-- Have to use version 1.2 since version 1.3 does not appear to work with ITDs --><version>1.2</version><dependencies><!-- You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>${org.aspectj-version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjtools</artifactId><version>${org.aspectj-version}</version></dependency></dependencies><executions><execution><goals><goal>compile</goal><goal>test-compile</goal></goals></execution></executions><configuration><outxml>true</outxml><source>${java-version}</source><target>${java-version}</target></configuration> </plugin>
这是引起所有问题的参考。 没有它,将使用默认值,并且该应用程序将运行。
- 更新
tomcat-maven-plugin
以进行自动部署。<plugin><groupId>org.codehaus.mojo</groupId><artifactId>tomcat-maven-plugin</artifactId><version>1.1</version><configuration><server>myserver</server><url>http://localhost:8080/manager/text</url></configuration> </plugin>
剩下下面的工作POM文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.captaindebug</groupId><artifactId>audit</artifactId><packaging>war</packaging><version>1.0.0-BUILD-SNAPSHOT</version><properties><java-version>1.7</java-version><org.springframework-version>3.2.3.RELEASE</org.springframework-version><org.aspectj-version>1.7.1</org.aspectj-version><org.slf4j-version>1.5.10</org.slf4j-version></properties><dependencies><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${org.springframework-version}</version><exclusions><!-- Exclude Commons Logging in favor of SLF4j --><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${org.springframework-version}</version></dependency><!-- AspectJ --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>${org.aspectj-version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${org.aspectj-version}</version></dependency><!-- Logging --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${org.slf4j-version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>jcl-over-slf4j</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${org.slf4j-version}</version><scope>runtime</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.15</version><exclusions><exclusion><groupId>javax.mail</groupId><artifactId>mail</artifactId></exclusion><exclusion><groupId>javax.jms</groupId><artifactId>jms</artifactId></exclusion><exclusion><groupId>com.sun.jdmk</groupId><artifactId>jmxtools</artifactId></exclusion><exclusion><groupId>com.sun.jmx</groupId><artifactId>jmxri</artifactId></exclusion></exclusions><scope>runtime</scope></dependency><!-- @Inject --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency><!-- Servlet --><dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- Test --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.7</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${java-version}</source><target>${java-version}</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><junitArtifactName>junit:junit</junitArtifactName></configuration></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>tomcat-maven-plugin</artifactId><version>1.1</version><configuration><server>myserver</server><url>http://localhost:8080/manager/text</url></configuration></plugin></plugins></build> </project>
最后……正确设置了项目设置,接下来要做的是继续执行代码,这是我下次要介绍的内容。
有关此代码和下一个博客的代码,请访问github: https : //github.com/roghughe/captaindebug/tree/master/audit-aspectj
翻译自: https://www.javacodegeeks.com/2013/07/auditing-a-spring-mvc-webapp-with-aspectj-part-1.html