【问题标题】:Spring Boot Rest - How to configure 404 - resource not foundSpring Boot Rest - 如何配置 404 - 找不到资源
【发布时间】:2016-08-12 12:13:23
【问题描述】:

我得到了一个有效的弹簧靴休息服务。当路径错误时,它不会返回任何内容。完全没有反应。同时它也不会抛出错误。理想情况下,我预计会出现 404 not found 错误。

我有一个 GlobalErrorHandler

@ControllerAdvice
public class GlobalErrorHandler extends ResponseEntityExceptionHandler {

}

ResponseEntityExceptionHandler中有这个方法

protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
                                                     HttpStatus status, WebRequest request) {

    return handleExceptionInternal(ex, null, headers, status, request);
}

我在我的属性中标记了error.whitelabel.enabled=false

我还必须做什么才能让此服务向客户端抛出 404 not found 响应

我参考了很多线程,没有看到任何人面临这个问题。

这是我的主要应用程序类

 @EnableAutoConfiguration // Sprint Boot Auto Configuration
@ComponentScan(basePackages = "com.xxxx")
@EnableJpaRepositories("com.xxxxxxxx") // To segregate MongoDB
                                                        // and JPA repositories.
                                                        // Otherwise not needed.
@EnableSwagger // auto generation of API docs
@SpringBootApplication
@EnableAspectJAutoProxy
@EnableConfigurationProperties

public class Application extends SpringBootServletInitializer {

    private static Class<Application> appClass = Application.class;

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(appClass).properties(getProperties());

    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public FilterRegistrationBean correlationHeaderFilter() {
        FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
        filterRegBean.setFilter(new CorrelationHeaderFilter());
        filterRegBean.setUrlPatterns(Arrays.asList("/*"));

        return filterRegBean;
    }

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    static Properties getProperties() {
        Properties props = new Properties();
        props.put("spring.config.location", "classpath:/");
        return props;
    }

    @Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
        WebMvcConfigurerAdapter webMvcConfigurerAdapter = new WebMvcConfigurerAdapter() {
            @Override
            public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
                configurer.favorPathExtension(false).favorParameter(true).parameterName("media-type")
                        .ignoreAcceptHeader(false).useJaf(false).defaultContentType(MediaType.APPLICATION_JSON)
                        .mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", MediaType.APPLICATION_JSON);
            }
        };
        return webMvcConfigurerAdapter;
    }

    @Bean
    public RequestMappingHandlerMapping defaultAnnotationHandlerMapping() {
        RequestMappingHandlerMapping bean = new RequestMappingHandlerMapping();
        bean.setUseSuffixPatternMatch(false);
        return bean;
    }
}

【问题讨论】:

    标签: java spring rest spring-mvc spring-boot


    【解决方案1】:

    解决方法很简单:

    首先您需要实现将处理所有错误情况的控制器。这个控制器必须有@ControllerAdvice——定义适用于所有@RequestMappings@ExceptionHandler是必需的。

    @ControllerAdvice
    public class ExceptionHandlerController {
    
        @ExceptionHandler(NoHandlerFoundException.class)
        @ResponseStatus(value= HttpStatus.NOT_FOUND)
        @ResponseBody
        public ErrorResponse requestHandlingNoHandlerFound() {
            return new ErrorResponse("custom_404", "message for 404 error code");
        }
    }
    

    @ExceptionHandler 中提供您想要覆盖响应的异常。 NoHandlerFoundException 是一个异常,当 Spring 无法委托请求时将生成(404 情况)。您还可以指定Throwable 来覆盖任何异常。

    其次你需要告诉 Spring 在 404 的情况下抛出异常(无法解析处理程序):

    @SpringBootApplication
    @EnableWebMvc
    public class Application {
    
        public static void main(String[] args) {
            ApplicationContext ctx = SpringApplication.run(Application.class, args);
    
            DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        }
    }
    

    我使用未定义的 URL 时的结果

    {
        "errorCode": "custom_404",
        "errorMessage": "message for 404 error code"
    }
    

    更新:如果您使用application.properties 配置SpringBoot 应用程序,则需要添加以下属性,而不是在main 方法中配置DispatcherServlet(感谢@mengchengfeng):

    spring.mvc.throw-exception-if-no-handler-found=true
    spring.web.resources.add-mappings=false
    

    【讨论】:

    • 谢谢。即使进行此更改后,我仍然没有看到任何响应。请帮忙!!!
    • 你能发布你的过滤器实现吗? CorrelationHeaderFilter 将处理每个请求,这可能是它不适合您的原因。我使用与您的代码非常接近的代码进行了测试,如果我评论过滤器、添加“@EnableWebMvc”并为它添加不需要的注释,例如“@EnableSwagger”、“@@EnableJpaRepositories”、“@@EnableAspectJAutoProxy”,它就可以工作。跨度>
    • 如果其他人在代码示例中遇到问题,当我使用属性而不是 main 内部配置调度程序 servlet 时,自定义 ControllerAdvice 适用于我的 Spring Boot 应用程序:spring.mvc.throw-exception-if-no-handler-found=true spring.resources.add-mappings=false 在我删除 main 中的 dispatcherServlet 配置并在 application.properties 中使用上述两个属性后,错误已正确路由到我的 ControllerAdvice。希望这对某人有帮助!
    • 请发布 ErrorResponse 类以完成此答案。
    • 这确实有帮助,但替换了 spring.resources.add-mappings=false,它在 Spring boot 2+ 中被 spring.web.resources.add-mappings=false 弃用。谢谢。
    【解决方案2】:

    我知道这是一个老问题,但这是在代码中而不是在主类中配置 DispatcherServlet 的另一种方法。您可以使用单独的@Configuration 类:

    @EnableWebMvc
    @Configuration
    public class ExceptionHandlingConfig {
    
        @Autowired
        private DispatcherServlet dispatcherServlet;
    
        @PostConstruct
        private void configureDispatcherServlet() {
            dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
        }
    }
    

    请注意,如果没有 @EnableWebMvc 注释,这将不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-03
      • 2016-11-28
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 1970-01-01
      相关资源
      最近更新 更多