控制器中的Spring AOP切入点
我已经定义了这个类方面,它可以很好地用于服务(除非用户具有角色管理器,否则不允许访问,但对控制器没有限制(?) 和导入控制器:控制器中的Spring AOP切入点,spring,spring-mvc,aop,spring-aop,Spring,Spring Mvc,Aop,Spring Aop,我已经定义了这个类方面,它可以很好地用于服务(除非用户具有角色管理器,否则不允许访问,但对控制器没有限制(?) 和导入控制器: @SuppressWarnings("deprecation") public class ImportController extends AbstractFormController { private String view; private String successView; @Autowired protected
@SuppressWarnings("deprecation")
public class ImportController extends AbstractFormController {
private String view;
private String successView;
@Autowired
protected UserService userService;
@Autowired
private ManageDeviceService manageDeviceService;
public String getView() {
return view;
}
public void setView(String view) {
this.view = view;
}
public String getSuccessView() {
return successView;
}
public void setSuccessView(String successView) {
this.successView = successView;
}
@Override
public ModelAndView processFormSubmission(final HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
final ModelAndView mav = new ModelAndView(getView());
FileUploadCommand file = (FileUploadCommand)command;
MultipartFile multipartFile = file.getFile();
if(multipartFile!=null && multipartFile.getSize()>0) {
Workbook workbook = Workbook.getWorkbook(multipartFile.getInputStream());
DataCollector dataCollector = new XLSDataCollector(workbook, true);
final List<Application> applications = manageDeviceService.loadApplications (dataCollector.getDataCollection());
List<ApplicationImporterError> importationErrors = manageDeviceService.validateApplications(applications);
savedApplications.add(manageDeviceService.getApplicationById(application.getId(), true));
}
return mav;
}
@Override
public ModelAndView showForm(HttpServletRequest request, HttpServletResponse arg1, BindException errors)
throws Exception {
return new ModelAndView(getView());
}
}
/**
* @param applications
* @param competentBody
* @return
* @throws Exception
*/
private List<Application> saveApplications(List<Application> applications,User user) throws Exception {
return manageDeviceService.saveImportedApplications (applications, user);
}
/**
* @param session
* @return
*/
public User getUser(HttpSession session) {
User user = (User) session.getAttribute(Const.SESSION_USER);
if (user == null) {
user = new User();
}
return user;
}
}
@SuppressWarnings(“弃用”)
公共类ImportController扩展了AbstractFormController{
私有字符串视图;
私有字符串成功视图;
@自动连线
受保护的用户服务用户服务;
@自动连线
专用管理设备服务管理设备服务;
公共字符串getView(){
返回视图;
}
公共void集合视图(字符串视图){
this.view=视图;
}
公共字符串getSuccessView(){
返回成功视图;
}
public void setSuccessView(字符串successView){
this.successView=successView;
}
@凌驾
公共模型和视图处理表单提交(最终HttpServletRequest请求,
HttpServletResponse,对象命令,BindException错误)
抛出异常{
final ModelAndView mav=新ModelAndView(getView());
FileUploadCommand文件=(FileUploadCommand)命令;
MultipartFile MultipartFile=file.getFile();
if(multipartFile!=null&&multipartFile.getSize()>0){
工作簿=Workbook.getWorkbook(multipartFile.getInputStream());
DataCollector DataCollector=新的XLSDataCollector(工作簿,true);
最终列表应用程序=manageDeviceService.loadApplications(dataCollector.getDataCollection());
List ImportionErrors=manageDeviceService.validateApplications(应用程序);
savedApplications.add(manageDeviceService.getApplicationById(application.getId(),true));
}
返回mav;
}
@凌驾
公共模型和视图显示表单(HttpServletRequest请求、HttpServletResponse arg1、BindException错误)
抛出异常{
返回新的ModelAndView(getView());
}
}
/**
*@param应用程序
*@param competintbody
*@返回
*@抛出异常
*/
私有列表保存应用程序(列表应用程序、用户)引发异常{
return manageDeviceService.saveImportedApplications(应用程序,用户);
}
/**
*@param会话
*@返回
*/
公共用户getUser(HttpSession会话){
User User=(User)session.getAttribute(Const.session\u User);
if(user==null){
user=新用户();
}
返回用户;
}
}
当我以UserRole.MANAGER的身份登录时,会调用之前的方法(JoinPoint _jp),否则不会调用
我明白了,当我在浏览器中粘贴URL时,不会调用之前的方法(JoinPoint\u jp)…
http://127.0.0.1:7001/devices/manage/import.do
Spring基于动态代理的AOP的一个限制是它只能从文档中建议公共连接点:
由于Spring的AOP框架基于代理的特性,受保护的方法根据定义是不被拦截的,既不适用于JDK代理(如果这不适用),也不适用于CGLIB代理(如果这在技术上是可能的,但不推荐用于AOP目的)。因此,任何给定的切入点将仅与公共方法匹配!
如果您的拦截需要包括受保护的/私有的方法,甚至是构造函数,则考虑使用Spring驱动的原生AspectJ编织而不是Spring基于代理的AOP框架。这构成了不同特性的AOP使用的不同模式,所以在作出决定之前一定要让自己熟悉编织。
您的许多控制器方法都受
保护
,因此,尽管您的控制器注册为SpringBean(可能),但非公共方法将不会得到建议。问题可能在于控制器对象本身调用了您试图拦截的方法(它们本来是受保护的),从抽象控制器直接调用其重写的方法之一。Spring AOP的工作方式是围绕对象创建一个代理来拦截这些方法,但只有通过Spring注入的依赖项从外部调用该方法时,该方法才起作用。这里不是这种情况,因为该方法是从它自己的对象内调用的,t他的调用绕过了为“外部世界”包装对象的任何代理。我遇到了与“存储库建议”相同的问题,但“控制器建议”不起作用。最后我找到了一个解决方案。简言之,你需要确保你的AOP定义是在Servlet上下文中加载的,而不是在不同的上下文中加载的
在我的例子中,我的SpringAOP定义是在从这里移动之后在tools config.xml
中定义的
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/tools-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
上下文配置位置
类路径:spring/tools-config.xml
org.springframework.web.context.ContextLoaderListener
到这里来,
<servlet>
<servlet-name>petclinic</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-core-config.xml, classpath:spring/tools-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
宠物诊所
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
类路径:spring/mvc-core-config.xml,类路径:spring/tools-config.xml
1.
控制器的建议正在运行。您已将问题标记为“spring security”那为什么不使用Spring Security呢?只是一个忠告——我会考虑在你提供的任何示例代码中模糊你公司的包名。不是答案而是另一个建议——因为你命名的切入点与<<代码> @之前的代码相同,你不需要在切入点表达式中完全限定它们。-
@Before(“handleImportController()| | handleDeviceServiceMethod()| |等)
应该可以工作,并且更简洁/可读。您是否尝试过调试Before方法,以查看是否实际调用了@Before
方法,或者用户
对象是否从getEcasUser()返回空值
出于某种原因-无论是哪种情况,您都不会知道,因为除非用户不知道,否则不会执行任何操作
<servlet>
<servlet-name>petclinic</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-core-config.xml, classpath:spring/tools-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>