Spring - 管理自定义异常页面

时间:2017-09-18 19:51:57

标签: spring

我尝试使用自定义异常管理自定义错误页面。 我有这个例外

@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Inesistente")
public class ResourceNotAccessibleException extends Throwable{

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


}

我想以404错误回复。 比我管理错误控制器

@ControllerAdvice
public class ErrorController {

@ExceptionHandler({ResourceNotAccessibleException.class})
    public ModelAndView getErrorPage(HttpServletRequest request, Throwable ex) {
        String errorMsg = "";
        int httpErrorCode = getErrorCode(request);


        switch (httpErrorCode) {
        case 404: {

            logger.error("Status Error " + httpErrorCode , ex.getMessage());
            errorMsg = messageSource.getMessage("errorMessage", new Object[] { uuid, +httpErrorCode }, locale);
            break;
        }
        case 400: {
            errorMsg = "BAD REQUEST";
            break;
        }

        case 500: {
            errorMsg = messageSource.getMessage("errorMessage", new Object[] { uuid, +httpErrorCode }, locale);
            logger.error("Status Error " + httpErrorCode , ex.getMessage());
            break;
        }
        }
        ModelAndView mav = new ModelAndView();
        mav.addObject("errorMsg", errorMsg);

        mav.setViewName("error");

        return mav;
    }

现在,在我的控制器中,如果我有类似

的东西
if(object==null) {
throw new ResourceNotAccessibleException("Resource does not exist");
}

我应该看到我的错误视图,但是我得到了经典的白色错误页面,在我的日志中我看到异常被点击..

2 个答案:

答案 0 :(得分:0)

ResourceNotAccessibleException应该延伸ExceptionRuntimeException而不是ThrowableMore info

如果您无法更改异常类型,可能您可以尝试ExceptionHandlerExceptionResolver或此awesome post关于Spring异常处理

还有一件事,你可能想要在getErrorPage之上添加一些@ResponseStatus信息,因为你正在处理这个例子而ResourceNotAccessibleException上方的@ResponseStatus注释永远不会触发。

所以我认为这样的事情应该有效:

@ControllerAdvice
public class ErrorController {

    @ResponseStatus(value= HttpStatus.NOT_FOUND) // <= important
    @ExceptionHandler({ResourceNotAccessibleException.class})
    public ModelAndView getErrorPage(HttpServletRequest request, Throwable ex) {
        String errorMsg = "";

        // ... some code here

        ModelAndView mav = new ModelAndView();
        mav.addObject("errorMsg", errorMsg);

        mav.setViewName("error");

        return mav;
    }
}


public class ResourceNotAccessibleException extends Exception{ // <= important

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

如果这不起作用,您还可以尝试将资源视图文件名更改为errorPage.jsperrorPage.html,并将其设置为mav.setViewName("errorPage");

答案 1 :(得分:0)

您需要更换网络容器中的默认错误网页,并将状态代码映射到特定的错误页面

以下是您需要进行的更改:

  1. 如果是 Jetty 容器,以下是更改:

    @Bean
    public JettyEmbeddedServletContainerFactory 
        containerFactory(
            @Value("${server.port:8080}") final String port,
            @Value("${jetty.threadPool.maxThreads:600}") final String maxThreads,
            @Value("${jetty.threadPool.minThreads:10}") final String minThreads,
            @Value("${jetty.threadPool.idleTimeout:5000}") final String idleTimeout) {
        final JettyEmbeddedServletContainerFactory factory =
                new JettyEmbeddedServletContainerFactory(Integer.valueOf(port));
    
        ...
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, 
             "/error-info.html"));
        ...
        return factory;
    }
    
  2. 如果是 Tomcat 容器,以下是更改:

    @Bean
    public EmbeddedServletContainerCustomizer container() {
         return new EmbeddedServletContainerCustomizer() {
    
            @Override
            public void customize(
                ConfigurableEmbeddedServletContainer container) {
                container.addErrorPages(new 
                    ErrorPage(HttpStatus.NOT_FOUND, "/error-info.html"));
    
            }
        };
    }
    
  3. 对于ErrorController请勿设置视图名称。它将从之前设置的错误页面映射中选择视图。

    @ControllerAdvice
    public class ErrorController {
    
        @ExceptionHandler(ResourceNotAccessibleException.class)
        @ResponseStatus(value = HttpStatus.NOT_FOUND)
        public ModelAndView handleResourceNotAccessibleException(
            HttpServletRequest req, ResourceNotAccessibleException ex) {
           ...
           ModelAndView mav = new ModelAndView();
           mav.addObject("errorMsg", errorMsg);
    
           retrun mav;
        }
     }
    
  4. error-info.html 的位置或resources/static下的jsp