在做Spring+Struts2+Hibernate+Shiro整合时遇到问题,记录一下。
框架环境
框架 | 版本 |
---|---|
Spring | 4.3.7 |
Struts | 2.3.24 |
Shiro | 1.2.3 |
问题描述
- Spring, Struts2, Shiro均使用注解方式。如果不加Shiro @RequiresPermissions注解,一切访问正常。一旦加上@RequiresPermissions后,访问
/user/op_test.action
报错java.lang.NullPointerException at com.lee.action.UserAction.test(UserAction.java:38)
,即userService.test()
这一行。Debug调试发现userService
字段为null
,即@Autowire
注解注入失效。 - 检查Shiro注解配置无误。
- UserAction代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@Controller
@Scope("prototype")
@Namespace("/user")
@ParentPackage("struts-default")
@Result(name="login",location="/index.jsp")
public class UserAction extends ActionSupport{
@Autowired(required=true)
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
@Action("op_test")
public String test(){
System.out.println("UserAction.test() executed.");
userService.test();
return LOGIN;
}
@Action("op_delete")
@RequiresPermissions("user-delete") //Shiro注解
public String delete(){
System.out.println("UserAction.delete() executed.");
return LOGIN;
}
}
|
尝试过程
- 根据这篇文章的提示,给
userService
加入setter
方法后问题还是依旧。
1
2
3
4
5
6
|
@Autowired
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
|
- 将
@Autowire
换为@Resource(type=xxx.class)
也不行。
解决办法
经多次摸索,有如下3种解决办法。由于对Spring注入时各注解的作用时机不清楚,具体原理尚不明:
第一种: 将Struts2的Action配置由注解方式改为struts.xml
配置
1
2
3
4
5
6
|
<package name="default" extends="struts-default" namespace="/user" strict-method-invocation="false">
<action name="op_*" class="userAction" method="{1}">
<result name="login">/index.jsp</result>
</action>
</package>
|
第二种:将UserAction的注解定义bean改为application.xml
中定义
1
2
3
4
|
<bean id="userAction" class="com.lee.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
|
然后给UserServiceImpl
指定id @Service("userService")
:
1
2
3
4
5
6
7
8
9
10
|
@Service("userService")
@Transactional
public class UserServiceImpl {
@Autowired
private UserDaoImpl userDao;
public void test(){
System.out.println("UserServiceImpl.test(): "+userDao);
}
}
|
第三种:推荐采用,保留注解方式
a. 给UserServiceImpl
指定id @Service("userService")
;
b. 然后给UserAction
中的userService
字段加入setter
方法。
c. 如上处理后,采用@Autowire
或@Resource
注入userService
即可。