`
jeooo.li
  • 浏览: 46141 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

当Struts2的Action继承ActionSupport时,利用AOP来拦截Action出现NoSuchMethodException when Aspec

阅读更多

今天做项目的时候,由于要用到在Struts2的Action类中利用Spring的AOP来实现记录操作日志,在Action里面的方法中加上自定义annotation来实现记录操作功能,运行的时候页面提示NoSuchMethodException when Aspec,网上说是Action继承了ActionSupport导致的,后来在一个英文网站上找到了解决的方法,只要在Spring的配置文件applicationContext中的<aop:aspectj-autoproxy/>改为<aop:aspectj-autoproxy proxy-target-class="true"/>就可以了。

英文网站的地址是:http://forum.springsource.org/showthread.php?t=51758,原文如下:

 

DefaultNoSuchMethodException when Aspecting classes

<!-- / icon and title --><!-- message -->

Hi everyone,

I'm new to Aspects and I'm having trouble configuring them inside Spring, I have some questions to ask:

First, configuration issues, I've got defined these beans provided by Appfuse (2.0):
Code:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
       default-lazy-init="true">

    <!-- =================================================================== -->
    <!-- AOP: Configuration and Aspects                                      -->
    <!-- =================================================================== -->
    <aop:config>
        <aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* *..service.UserManager.*(..))" order="0"/>        
        <aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* *..service.UserManager.saveUser(..))" order="1"/>
        <aop:advisor id="managerTx" advice-ref="txAdvice" pointcut="execution(* *..service.*Manager.*(..))" order="2"/>
    </aop:config>
    
    <!-- Enable @Transactional support -->
    <tx:annotation-driven/>
    
    <!-- Fix bug in Spring 2.0.6: http://issues.appfuse.org/browse/APF-887 -->
    <bean class="org.springframework.transaction.aspectj.AnnotationTransactionAspect" factory-method="aspectOf" dependency-check="none" lazy-init="false">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
    
    <!-- Enable @AspectJ support -->
    <aop:aspectj-autoproxy/>

    <!-- Enable @Configured support -->
    <aop:spring-configured/>
    
    <tx:advice id="txAdvice">
        <tx:attributes>
            <!-- Read-only commented out to make things easier for end-users -->
            <!-- http://issues.appfuse.org/browse/APF-556 -->
            <!--tx:method name="get*" read-only="true"/-->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <tx:advice id="userManagerTxAdvice">
        <tx:attributes>
            <tx:method name="save*" rollback-for="UserExistsException"/>
        </tx:attributes>
    </tx:advice>
    
    <bean id="userSecurityAdvice" class="org.appfuse.service.UserSecurityAdvice"/>
    
    [...]
These beans are defined inside an applicationContext file inside one of appfuse jars, so I cannot change them (although I do overwrite some other appfuse bean). I do need to keep the aop:config section, as it being used by our application.

And I've also defined (in our own applicationContext file) a couple of beans to implement logging when some subpackaging is detected or when detecting some annotations:

Code:
  <bean id="aLogInterceptor" class="com.bungee.aspects.AnnotationLoggerInterceptor" />
  <bean id="cpLogInterceptor" class="com.bungee.aspects.PackagesLoggerInterceptor" />
Next the @AspectJ class:

Code:
@Aspect
public class PackagesLoggerInterceptor {

    @Before( "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )" )
    public void beforeMethod( JoinPoint jp ) {
	// logging in here
    }
    
    @AfterReturning( pointcut = "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )", returning="retVal" )
    public void afterMethod( JoinPoint jp, Object retVal ) {
	// more logging in here...
    }
    
    @AfterThrowing( pointcut = "execution( * com.bungee..*.*(..) ) && !execution( * com.bungee.aspects.*.*(..) )", throwing="ex" )
    public void afterException( JoinPoint jp, Throwable ex ) {
	// ... and finish logging here
    }
    
}
Ok, first problem in here, I've got some Struts2 actions under package com.bungee.webapp.action. Each time one of those classes gets invoked I've got the same type of Exception:


Code:
java.lang.NoSuchMethodException: $Proxy361.initHome()
	at java.lang.Class.getMethod(Class.java:1605)
	at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:55)
	at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:41)
	at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
	at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
	at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
	at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
	at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
	at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
	at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
	at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
	at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
	at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167)
	at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
	at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
[...]
I've readed about aspects aren't getting well proxied, but I haven't been able neither to configure them properly nor finding how to do it. Any help would be greatly appreciated O:-)

Second issue, is @AfterThrowing well defined (I want to catch all type of Exceptions)?? I'm not very sure

And last issue, this time regarding AnnotationLoggerInterceptor: that class has more or less the same methods as PackagesLoggerInterceptor but changing the annotations to check for annotated methods or classes, so pointcuts are defined as follows:
Code:
@annotation( com.bungee.annotations.Loggeable )
Does this captures annotated classes and methods or only annotated methods?? I find Spring documentation a little unclear at this point.

I'm using AspectJ 1.5.3, Spring 2.0.6, Apffuse2.0 (Struts2 + ibatis flavour) and Java6

Thanks in advance!



found what was going wrong by myself: As noted several -lots of- times on this forum, I had to use proxy-target-class attribute, in order to use our Aspect (also) with Struts2 action classes, as jdk-proxies only work with interfaces.

Code:
<aop:aspectj-autoproxy proxy-target-class="true"/>
The problem was, this bean was declared in an applicationContext file inside an appfuse jar, without this attribute. I was trying to overwrite this bean on our own applicationContext file (which is setted to load afterwards), but it seems that Springs does not overwrite it, hence the error. We've moved all beans declared inside the appfuse jar to our applicationContext file, redeclared autoproxy as noted above, and removed this appfuse's applicationContext file from our list of applicationContext files.

Regards,
Michael K.
分享到:
评论

相关推荐

    Struts2继承ActionSupport例子

    Struts2继承ActionSupport例子 这个是我们在上课的时候做的一个小例子,可能其中还掺杂着其他东西,跟我博客是相关联的,如果只看代码看不懂,建议大家去看一下博客。

    自定义Action继承ActionSupport实现简单登录

    自定义Action继承ActionSupport实现简单登录,刚开始学习struts2记录一下。

    struts 2 基础2__继承ActionSupport完成输入校验

    struts 2 基础 __继承ActionSupport完成输入校验

    Struts2的特点

    实现Action时有时会继承于ActionSupport, 覆盖execute方法,从而创建一个Action。 因为ActionSupport提供了很多方法可以为开发提供方便。 3、支持依赖注入,主要借助于spring来实现 4、支持拦截处理,相当于...

    Struts2 in action中文版

    4.3 研究内建的Struts 2拦截器 67 4.3.1 工具拦截器 67 4.3.2 数据转移拦截器 67 4.3.3 工作流拦截器 69 4.3.4 其他拦截器 72 4.3.5 内建的拦截器栈 73 4.4 声明拦截器 74 4.4.1 声明独立的拦截器和拦截器栈 74 ...

    Struts1与Struts2本质区别

    1 在Action实现类方面的对比:Struts 1要求Action类继承一个抽象基类;Struts 1的一个具体问题是使用抽象类编程而不是接口。Struts 2 Action类可以实现一个Action接口,也可以实现其他接口,使可选和定制的服务成为...

    Spring和Struts整合---继承ActionSupport的方法

    NULL 博文链接:https://carmark.iteye.com/blog/450978

    struts1.0和struts2

    ◆Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。 ◆Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个...

    struts1和struts2的区别

    虽然,在理论上Struts2的Action无须实现任何接口或者是继承任何的类,但是,在实际编程过程中,为了更加方便的实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并且重载(Override)此类...

    ActionSupport与action区别1

    1.实现Action 接口 (implements Action) 2.继承ActionSupport类 (extends ActionSupport) 实际上

    struts2讲义_吴峻申

    9.2.2 Struts2Action范围属性文件国际化应用 187 9.2.3 Struts2临时范围属性文件国际化应用 188 9.3 用户主动选择国际化应用介绍 191 第10章 Struts2页面布局实现 194 10.1 sitemesh基本使用方法 194 10.2 sitemesh...

    Struts 2.0的Action讲解

    Struts 2.0的Action讲解 com.opensymphony.xwork2.ActionSupport类

    struts2 Action编写方式

    Action类的三种编写方式。POJO,实现Action类,继承ActionSupport。实例代码。

    使用Spring , ActionSupport ,struts1整合实例

    使用Spring , ActionSupport ,struts1整合实例,一个简单的实例代码

    默然说话struts2入门2-标签及ActionSupport.rar-part1

    入门级,无声视频,这一集比上一集感觉拍得好多了,找到一些窍门。 对Struts2的标签导入,错误信息显示,ActionSupport类的addFieldError()方法,validate()方法,execute()方法的使用进行了介绍。

    【张冰Struts2学习笔记】0201_Action接口与ActionSupport类

    NULL 博文链接:https://coderdream.iteye.com/blog/812871

    搭建好的一个struts2环境

    为了方便初学者使用Struts2,我配置了一个Struts2空项目,可以直接使用Struts2,IDE使用的是MyEclipse6.5 使用方法: 1.在包com.test.web.action添加类,比如Test1Action.java,该类需要继承ActionSupport 2.在Web...

    默然说话struts2入门2-标签及ActionSupport.rar-part2

    入门级,无声视频,这一集比上一集感觉拍得好多了,找到一些窍门。 对Struts2的标签导入,错误信息显示,ActionSupport类的addFieldError()方法,validate()方法,execute()方法的使用进行了介绍。

    java 请求的方法不存在(NoSuchMethodException)

    java 请求的方法不存在(NoSuchMethodException) java 请求的方法不存在(NoSuchMethodException)

Global site tag (gtag.js) - Google Analytics