来自同一个 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;
}
有几个选项。其中一些是:
您可以使用request.getUserPrincipal()
检查用户是否已通过身份验证。如果用户未通过身份验证,return 值将为 null
。根据结果,您可以 return 不同的视图。
让所有控制器服务 public 页面从一个 PublicBaseController 扩展,控制器服务私有页面扩展 PrivateBaseController。将用 @ExceptionHandler
注释的方法添加到基础控制器,return 适当的视图。
在我当前的 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;
}
有几个选项。其中一些是:
您可以使用
request.getUserPrincipal()
检查用户是否已通过身份验证。如果用户未通过身份验证,return 值将为null
。根据结果,您可以 return 不同的视图。让所有控制器服务 public 页面从一个 PublicBaseController 扩展,控制器服务私有页面扩展 PrivateBaseController。将用
@ExceptionHandler
注释的方法添加到基础控制器,return 适当的视图。