Spring MVC @例外处理程序的顺序

vyu0f0g1  于 2023-03-03  发布在  Spring
关注(0)|答案(3)|浏览(139)

我使用@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);
    }
}
    • 更新**

我发现顺序是不是随机的实际上抛出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,还是有其他解决方案?

xwbd5t1u

xwbd5t1u1#

使用注解**@Order或为@ControllerAdvice实现接口Ordered**。
请参阅以下内容的实现:

*异常处理程序方法解析程序
*异常处理程序异常解析程序类(方法初始化异常处理程序建议缓存
*注解AwareOrderComparator

hgtggwj0

hgtggwj02#

我们正在使用异常处理程序在下面的方式,从来没有顺序得到混合,它的工作预期。所以,这可能是可能的,如果你将使用它作为下面的例子,那么它将解决你的问题

处理程序类

@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,因为首先它将搜索匹配的异常,如果没有找到,则转到父处理程序
如果我们抛出新的NullPointerException(),则它将搜索匹配的处理程序,但在本例中未找到,然后查找parent,即handle1
有关详细信息,请参阅here
希望对你有帮助,谢谢

bkhjykvo

bkhjykvo3#

只要项目中只有一个controlleradvice类,就没有顺序/优先级。但如果有多个controlleradvice类,则可以设置顺序。但在您的情况下,顺序不适用,因为两个异常的处理方式不同(即UnauthorizedException和Exception)。
好的方面是,Spring将自动找到相应的自定义Exception类(如果有的话,否则就是泛型Exception)并调用相应的方法。
有关Spring控制器建议和异常处理的更多信息,请参阅:https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

相关问题