小弟碰到一个问题,在struts2的Action方法上做一个权限判断的切面,出现了ClassCastException问题。
首先,先说明一下,常规情况下是不会出现这个问题,什么是特殊情况?请详细看我下面例子: 现有两个Action,分别位于不同的包中1.com.hanssion.action 包含TestAction2.com.keven.action 包含TestAction(跟上面那个包名字一样,这无关紧要)两个action都继承了ActionSupport类。为这两个action配置不同的命名空间:
<package name="struts-test" extends="struts-default" namespace="/test">
<action name="*!*" class="com.keven.action.{1}Action" method="{2}">
<result>${url}</result>
</action>
</package>
<package name="struts-test2" extends="struts-default" namespace="/test2">
<action name="*^*" class="com.hanssion.action.{1}Action" method="{2}">
<result>${url}</result>
</action>
</package>ok,struts这边配置搞定,继续。写了一个pojo,里面的方法作为周围通知的处理方法。package com.keven.advice;import org.aspectj.lang.ProceedingJoinPoint;
public class AopAdviceHandler {
public Object doAround(ProceedingJoinPoint jp) throws Throwable{
System.out.println(jp.getTarget().getClass().getName());
System.out.println(jp.getSignature().getName());
System.out.println("周围通知执行!");
return jp.proceed();
}
}
然后在spring中,为位于不同包的两个action配置上周围通知,如下:<bean id="handler1" class="com.keven.advice.AopAdviceHandler" scope="prototype">
</bean>
<aop:config proxy-target-class="true">
<aop:aspect ref="handler1" >
<aop:around method="doAround" pointcut="execution(* com.keven.action.TestAction.*(..))" />
</aop:aspect>
</aop:config>
<aop:config proxy-target-class="true">
<aop:aspect ref="handler1" >
<aop:around method="doAround" pointcut="execution(* com.hanssion.action.TestAction.*(..))" />
</aop:aspect>
</aop:config>
一切就绪,补上两个action的代码:com.hanssion.action.TestAction的代码:public class TestAction extends BaseAction {
private static final Log log = LogFactory.getLog(TestAction.class); //日志类
private static final String PAGE_TONAV = "/nav2.jsp"; //导航页
public String toNav2(){
log.info("进入导航菜单页2");
url = PAGE_TONAV;
return SUCCESS;
}
}
com.keven.action.TestAction的代码:public class TestAction extends BaseAction {
private static final Log log = LogFactory.getLog(TestAction.class); //日志类
private static final String PAGE_TONAV = "/nav.jsp"; //导航页
public String toNav(){
log.info("进入导航菜单页");
url = PAGE_TONAV;
return SUCCESS;
}
} jsp页面(只写出body部分):
nav.jsp
<body>
这是菜单导航页
<s:action name="Test^toNav2" namespace="/test2" executeResult="true"></s:action>
</body> nav2.jsp
<body>
这是菜单导航页2
</body>
好了,现在我说一下出现问题的情况和不出现问题的情况。1.不出错的情况,只要我将nav.jsp的红色代码去掉,就正常运行,因为此时只请求了com.keven.action.TestAction 的toNav方法。在后台中打印如下:com.keven.action.TestAction
toNav
周围通知执行!
2010-5-30 23:50:11 com.keven.action.TestAction toNav
信息: 进入导航菜单页
2.出错的情况:但不去掉nav.jsp中的红色代码时,执行出错提示如下异常(包括打印出来的信息):2010-5-30 23:51:59 com.keven.action.TestAction toNav
信息: 进入导航菜单页
com.keven.action.TestAction
toNav
周围通知执行!2010-5-30 23:52:00 com.opensymphony.xwork2.util.logging.commons.CommonsLogger error
严重: Could not execute action: /test2/Test^toNav2
java.lang.ClassCastException: com.keven.action.TestAction cannot be cast to com.hanssion.action.TestAction
at com.hanssion.action.TestAction$$FastClassByCGLIB$$8e7bfbd2.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at com.hanssion.action.TestAction$$EnhancerByCGLIB$$2c80dd7e.toNav2(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
......略
为什么?debug了一下,并未执行到请求com.hanssion.action.TestAction.toNav2()时的周围通知方法doAround就出错了,高手何在,牛人何在,望解答。
首先,先说明一下,常规情况下是不会出现这个问题,什么是特殊情况?请详细看我下面例子: 现有两个Action,分别位于不同的包中1.com.hanssion.action 包含TestAction2.com.keven.action 包含TestAction(跟上面那个包名字一样,这无关紧要)两个action都继承了ActionSupport类。为这两个action配置不同的命名空间:
<package name="struts-test" extends="struts-default" namespace="/test">
<action name="*!*" class="com.keven.action.{1}Action" method="{2}">
<result>${url}</result>
</action>
</package>
<package name="struts-test2" extends="struts-default" namespace="/test2">
<action name="*^*" class="com.hanssion.action.{1}Action" method="{2}">
<result>${url}</result>
</action>
</package>ok,struts这边配置搞定,继续。写了一个pojo,里面的方法作为周围通知的处理方法。package com.keven.advice;import org.aspectj.lang.ProceedingJoinPoint;
public class AopAdviceHandler {
public Object doAround(ProceedingJoinPoint jp) throws Throwable{
System.out.println(jp.getTarget().getClass().getName());
System.out.println(jp.getSignature().getName());
System.out.println("周围通知执行!");
return jp.proceed();
}
}
然后在spring中,为位于不同包的两个action配置上周围通知,如下:<bean id="handler1" class="com.keven.advice.AopAdviceHandler" scope="prototype">
</bean>
<aop:config proxy-target-class="true">
<aop:aspect ref="handler1" >
<aop:around method="doAround" pointcut="execution(* com.keven.action.TestAction.*(..))" />
</aop:aspect>
</aop:config>
<aop:config proxy-target-class="true">
<aop:aspect ref="handler1" >
<aop:around method="doAround" pointcut="execution(* com.hanssion.action.TestAction.*(..))" />
</aop:aspect>
</aop:config>
一切就绪,补上两个action的代码:com.hanssion.action.TestAction的代码:public class TestAction extends BaseAction {
private static final Log log = LogFactory.getLog(TestAction.class); //日志类
private static final String PAGE_TONAV = "/nav2.jsp"; //导航页
public String toNav2(){
log.info("进入导航菜单页2");
url = PAGE_TONAV;
return SUCCESS;
}
}
com.keven.action.TestAction的代码:public class TestAction extends BaseAction {
private static final Log log = LogFactory.getLog(TestAction.class); //日志类
private static final String PAGE_TONAV = "/nav.jsp"; //导航页
public String toNav(){
log.info("进入导航菜单页");
url = PAGE_TONAV;
return SUCCESS;
}
} jsp页面(只写出body部分):
nav.jsp
<body>
这是菜单导航页
<s:action name="Test^toNav2" namespace="/test2" executeResult="true"></s:action>
</body> nav2.jsp
<body>
这是菜单导航页2
</body>
好了,现在我说一下出现问题的情况和不出现问题的情况。1.不出错的情况,只要我将nav.jsp的红色代码去掉,就正常运行,因为此时只请求了com.keven.action.TestAction 的toNav方法。在后台中打印如下:com.keven.action.TestAction
toNav
周围通知执行!
2010-5-30 23:50:11 com.keven.action.TestAction toNav
信息: 进入导航菜单页
2.出错的情况:但不去掉nav.jsp中的红色代码时,执行出错提示如下异常(包括打印出来的信息):2010-5-30 23:51:59 com.keven.action.TestAction toNav
信息: 进入导航菜单页
com.keven.action.TestAction
toNav
周围通知执行!2010-5-30 23:52:00 com.opensymphony.xwork2.util.logging.commons.CommonsLogger error
严重: Could not execute action: /test2/Test^toNav2
java.lang.ClassCastException: com.keven.action.TestAction cannot be cast to com.hanssion.action.TestAction
at com.hanssion.action.TestAction$$FastClassByCGLIB$$8e7bfbd2.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
at com.hanssion.action.TestAction$$EnhancerByCGLIB$$2c80dd7e.toNav2(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
......略
为什么?debug了一下,并未执行到请求com.hanssion.action.TestAction.toNav2()时的周围通知方法doAround就出错了,高手何在,牛人何在,望解答。
解决方案 »
- SSH框架测试时报错啊,谁来给我看看啊,谢谢啦
- 关于Java的两个效率问题
- jpa持久化
- 用Dreamweaver做jsp时为什么连接不上Mysql数据库呢?
- xp系统为什么不识别以jsp后缀名的文件呢?
- 请大家推荐个10000元左右的web服务器配置.
- 请给个spring的remoting.httpinvoker成功进行远程调用的例子原码?
- STRUTS1.1中用<html:errors/>,中文不能正确显示?
- 用iterator构造一个餐单table 然后想要每行有增减数量的按钮和显示数量的text怎么实现
- 贴了几个论坛,发现没人能解决这个问题
- struts2 表单路径传参数 ,在action中怎么接收不到?急!!
- spring整合JPA报错,请教!(JPA已经测试成功)
自己本来就有的功能. 需要交给人家的框架去做吗.?
拦截器的doInterceptor方法中, 你在ActionInvocation.invoke之前之后可以执行你想执行的代码.!
犯不着用Spring
针对这问题,有其他方法可以实现功能虽好,但还是希望知道这种做法出现这种错误的真相及解决方案。
你不会说你的web项目用main去执行吧.?
你要实现什么功能在拦截器里面干不就好了.? 你别的类需要AOP单独配, 至少action不用你这么去搞.!
比如Action中method方法中分别调用method1,method2来读取内容,而method1和method2都可根据读回不同的数据。这个在拦截器没法控制吧。
用aop+注解就可以实现。
一个请求请求Action中的method方法:public String method(){
List list1 = method1(); //分别调用method1和method2
List list2 = method2();
}
拦截器如何控制list1和list2跟权限有关的返回值?
另外你可看下我的struts配置,就是如你说的通配符配法。
PS:讨论太远了,回到这个问题,我急切想知道答案,为什么出现ClassCastException
你那两个Action有转换的关系.?
com.keven.action.TestAction cannot be cast to com.hanssion.action.TestAction
看到这个, 不同的两个类虽然都是BaseAction的子类!
你看看你关于AOP的配置那里是否出问题了.!
public String method(){
List list1 = method1(); //分别调用method1和method2
List list2 = method2();
}你用Spring能控制他里面调用关于权限的.? 好像没这种功能.!
代理只能控制在你执行你代理的类里面的方法之前或者之后干一些事情, 至于说这些被代理的方法(这里就是action的方法) , 你能控制得了吗.?可能是我没看明白, 也可能是你没说太明白.. 都纠结了.!
joinpoint.proceed()方法。
某些工作台功能使用这个是挺不错的,再配合注解来实现,开发前期就可以完全不理会权限相关问题了。
需要一个对struts2源码和spring源码甚至aspectj源码看得较深的人来解答一下。
自己却是没时间看啊~
Spring我都是来了什么问题现去看的, 所以有什么s2的要解决的东西无所谓.! Spring不好说.!
现在也没以前那么多时间去看那玩意, 毕竟还是有很多事情要忙的.!最近写文档把人写得五心烦躁.!等一个Spring玩得特别透的人进来看看吧.!
期待答案中..........
http://topic.csdn.net/u/20100615/09/3a1c204a-08bb-4896-851d-34fd13c28634.html