Spring ControllerAdvice中未处理404异常

时间:2019-01-09 18:28:57

标签: java spring spring-boot spring-mvc error-handling

我有一个简单的Spring MVC应用程序,我想在其中使用@ControllerAdvice处理所有未映射的url。 这是控制器:

@ControllerAdvice
public class ExceptionHandlerController {
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    public String handle404() {
        return "exceptions/404page";
    }
}

仍然,每次都会获得Whitelabel错误页面。

我尝试使用RuntimeException.classHttpStatus.BAD_REQUEST并使用NoHandlerFoundException扩展类,但没有用。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

要使其工作,您需要在DispecherServlet上设置throwExceptionIfNoHandlerFound属性。您可以执行以下操作:

spring.mvc.throwExceptionIfNoHandlerFound=true

application.properties文件中,否则请求将始终转发到默认servlet,并且将引发NoHandlerFoundException。

问题是,即使使用此配置,它也不起作用。从文档中:

  

请注意,如果   org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler是   使用,则请求将始终转发到默认servlet   并且在这种情况下永远不会引发NoHandlerFoundException。

因为默认情况下Spring Boot使用org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,所以您必须使用自己的WebMvcConfigurer覆盖它:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        // Do nothing instead of configurer.enable();
    }
} 

当然,上述情况在您的情况下可能会更复杂。

答案 1 :(得分:1)

另一种方法是ErrorController

@Controller
public class MyErrorController implements ErrorController {

    @GetMapping("/error")
    public ModelAndView errorHandler(HttpServletRequest req) {
        // Get status code to determine which view should be returned
        Object statusCode = req.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        // In this case, status code will be shown in a view
        ModelAndView mav = new ModelAndView("error_default");
        mav.addObject("code", statusCode.toString());
        return mav;
    }

    public String getErrorPath() {
        return "/error";
    }
}