来自同一个 ExceptionHandler 的多个错误页面

Multiple error pages from the same ExceptionHandler

在我当前的 spring-boot 项目中,我有这个 ExceptionHandler:

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
        if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
            throw error;

        ModelAndView mav = new ModelAndView();
        mav.setAttribute("error", error);
        return mav;
    }

}

我想做的是让这个处理程序重定向到不同的错误页面,具体取决于错误的来源。

我的项目中有两个 "types" 页面:一个 public 页面,由匿名用户或经过身份验证的用户访问,以及管理页面(私有),仅由经过身份验证的用户访问用户。

这两种类型的页面有不同的风格。我想,当用户在 public 页面中发生错误时,将显示具有 public 样式的错误页面。如果用户在隐私页面时发生错误,则显示另一个错误页面,具有隐私页面的样式。

您可以选择需要在您的控制器中抛出的异常classes,假设是这样的:

@RequestMapping(value = "/check")
 public ModelAndView processUser( ) throws Exception {
        ModelAndView modelAndView = new ModelAndView();

        if (something... ) {
            throw new GlobalDefaultExceptionHandler( );  // throws GlobalDefaultExceptionHandler
        }
        if (something else... ) {
            throw new AnotherExceptionHandler( );// throws 'anotherExceptionHandler'
        }

     // If there isn't exception thrown....do something

 }

假设这是 AnotherExceptionHandler class:

@ControllerAdvice
public class AnotherExceptionHandler{

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
        if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
            throw error;

        // Go to another view
        ModelAndView mav = new ModelAndView();
        mav.setAttribute("anotherError", error);
        return mav;
    }

}

但是如果你被迫只使用一个处理程序,你可以直接使用选择:

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {

 ModelAndView mav =null;

        if ( // something...){
         mav = new ModelAndView()
         mav.setAttribute("error", ... );
         return mav;
          } 

         else if (// another something...){
           mav = new ModelAndView()
           mav.setAttribute("anotherError", ...);
           return mav;
          }

return mav;

}

有几个选项。其中一些是:

  1. 您可以使用request.getUserPrincipal()检查用户是否已通过身份验证。如果用户未通过身份验证,return 值将为 null。根据结果​​,您可以 return 不同的视图。

  2. 让所有控制器服务 public 页面从一个 PublicBaseController 扩展,控制器服务私有页面扩展 PrivateBaseController。将用 @ExceptionHandler 注释的方法添加到基础控制器,return 适当的视图。