将Spring(4.2.4)与MVC(4.2.4)和安全性(4.0.3)一起使用。我已经实现了一个AccessDecisionManager,并且从我的决定方法中我抛出一个异常:
public void decide(
Authentication authentication,
Object object,
Collection<ConfigAttribute> configAttributes
) throws AccessDeniedException, InsufficientAuthenticationException {
FilterInvocation fi = (FilterInvocation) object;
String requestUrl = fi.getRequestUrl();
...
throw new SessionCompanyNotRoleTableCompanyException(1, 2);
...
throw new AccessDeniedException("Access denied!");
}
我既不能抓住“SessionCompanyNotRoleTableCompanyException
”也不能抓住AccessDeniedException
。我尝试过使用全局异常处理程序:
@Component
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(SessionCompanyNotRoleTableCompanyException.class)
public ModelAndView sessionCompanyNotRoleTableCompany() {
log.debug("SessionCompanyNotRoleTableCompanyException captured in GlobalExceptionHandler");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
@ExceptionHandler(Exception.class)
public ModelAndView exception(ModelMap model) {
log.debug("Exception captured in GlobalExceptionHandler");
String reason = "General Exception";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
}
我甚至创建了ExceptionResolver类,如:
@Component
public class SessionCompanyNotRoleTableCompanyExceptionResolver implements HandlerExceptionResolver, Ordered {
private static final Logger log = LoggerFactory.getLogger(SessionCompanyNotRoleTableCompanyExceptionResolver.class);
private int order;
@Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex
) {
if (ex instanceof SessionCompanyNotRoleTableCompanyException) {
log.debug("SessionCompanyNotRoleTableCompanyException captured in SessionCompanyNotRoleTableCompanyExceptionResolver");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
return null;
}
@Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
...并在我的web-config-class中初始化它们,如:
@Bean
public SessionCompanyNotRoleTableCompanyExceptionResolver createSessionCompanyNotRoleTableCompanyExceptionResolver() {
SessionCompanyNotRoleTableCompanyExceptionResolver resolver = new SessionCompanyNotRoleTableCompanyExceptionResolver();
resolver.setOrder(1);
return resolver;
}
这些工作,即只有在从控制器抛出异常时才会捕获异常。但不是decide
中的AccessDecisionManager
- 方法。
我应该实现什么以及如何实现可以在控制器之外(之前)捕获这些内容的东西?
编辑(添加SessionCompanyNotRoleTableCompanyException
以显示其定义):
public class SessionCompanyNotRoleTableCompanyException extends RuntimeException {
private static final long serialVersionUID = 1L;
public SessionCompanyNotRoleTableCompanyException(Long contextCompanyId, Long tableId) {
super("Context companyId: " + contextCompanyId + ", tableId: " + tableId);
}
}