@ExceptionHandler的顺序

时间:2016-07-19 15:21:14

标签: java spring spring-mvc

我使用@ControllerAdvice来处理我的所有应用外例:

@ControllerAdvice
public class ExceptionHandlingController {

  @ExceptionHandler({UnauthorizedException.class})
  public String unauthorizedException()  {
        .........
  }


  @ExceptionHandler({UnauthorizedAjaxException.class})
  @ResponseBody
  public void unauthorizedAjaxException()  {
        .........
  }

  @ExceptionHandler({Exception.class})
  public String globalException(){
        .........
  }


}

在我的代码的某个地方,我throw new UnauthorizedException();

   @Around("@annotation(Authenticated)")
   public Object profilingAuthentication(ProceedingJoinPoint pjp) throws Throwable  {

       HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

       if( request.getSession().getAttribute("idContact") == null ) {
            if( "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) )
                throw new UnauthorizedAjaxException();
            throw new UnauthorizedException();
       } 
       return pjp.proceed();
   }

但遗憾的是,Spring MVC似乎是通过使用最通用的案例(Exception)而不是更具体的案例(例如UnauthorizedException)来随机行动的。有时他会选择正确的!

订单如何运作?有没有办法指定订单?

UnauthorizedException是自定义异常

public class UnauthorizedException extends Exception {

    public UnauthorizedException(){
        super();
    }

    public UnauthorizedException(String message){
        super(message);
    }
}

更新

我发现它的命令 not rondom 实际上抛出UnauthorizedException的方法正常工作但其他方法没有正常工作!

@Authenticated
@RequestMapping(value="/favoris") 
public String favoris(ModelMap model, HttpServletRequest request) 
      throws UnauthorizedException {
    ....
}

@Authenticated
@RequestMapping(value="/follow") 
public String follow(ModelMap model, HttpServletRequest request) {
    .....
}

所以我必须手动添加throws UnauthorizedException或者还有其他一些解决方案吗?

3 个答案:

答案 0 :(得分:0)

我们正在以下列方式使用异常处理程序,并且从不对命令进行混合,并且它按预期工作。 因此,如果您将其用作以下示例,那么它将有可能解决您的问题

**********处理程序类******************

@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = Exception.class)
    public boolean handle1(Exception exc) {
        System.out.println("#####Global Exception###" + exc);
        exc.printStackTrace(System.out);
        return true;
    }

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = CustomException.class)
    public boolean handle2(CustomException exc) {
        System.out.println("###custom exception######" + exc);
        exc.printStackTrace(System.out);
        return true;
    }
}

***************控制器类************

@RestController("test")
@RequestMapping("/test1")
public class TestController {

    @RequestMapping("/t1")
    public boolean test() {
        if (true) {
            throw new CustomException();
        }
        return true;
    }
}

在上面的例子中,habdler是 handle2 ,因为首先它会搜索匹配的异常,如果没有找到则转到parrent处理程序

如果我们抛出新的NullPointerException(),那么它将搜索匹配的处理程序,但在这种情况下找不到,然后去找 handle1

的parrent

了解更多信息,请参阅here

我希望它会对你有所帮助。感谢

答案 1 :(得分:0)

使用注释 @Order 或为 @ControllerAdvice 实施 Ordered 界面。

见实现:

  • ExceptionHandlerMethodResolver
  • ExceptionHandlerExceptionResolver 类(方法 initExceptionHandlerAdviceCache
  • AnnotationAwareOrderComparator

答案 2 :(得分:-2)

只要您的项目中有一个controlleradvice类,就没有顺序/优先级。但是如果你有多个controlleradvice类,你可以设置Order。但是在这种情况下,顺序不适用,因为两个异常的处理方式不同(即UnauthorizedException和Exception)。

  

好处是,Spring会自动找到相应的自定义Exception类(如果有的话,   否则是通用的异常)并调用相应的方法。

请参阅有关Spring Controller建议和异常处理的更多信息: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc