简体   繁体   English

Spring Boot Rest - 如何配置 404 - 找不到资源

[英]Spring Boot Rest - How to configure 404 - resource not found

I got a working spring boot rest service.我有一个工作弹簧靴休息服务。 When the path is wrong it doesn't return anything.当路径错误时,它不会返回任何内容。 No response At all.完全没有反应。 At the same time it doesn't throw error either.同时它也不会抛出错误。 Ideally I expected a 404 not found error.理想情况下,我预计会出现 404 not found 错误。

I got a GlobalErrorHandler我有一个 GlobalErrorHandler

@ControllerAdvice
public class GlobalErrorHandler extends ResponseEntityExceptionHandler {

}

There is this method in ResponseEntityExceptionHandler ResponseEntityExceptionHandler中有这个方法

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

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

I have marked error.whitelabel.enabled=false in my properties我在我的属性中标记error.whitelabel.enabled=false

What else must I do for this service to throw a 404 not found response back to clients我还必须做什么才能让此服务向客户端抛出 404 not found 响应

I referred a lot of threads and don't see this trouble faced by anybody.我参考了很多线程,没有看到任何人面临这个麻烦。

This is my main application class这是我的主要应用程序类

 @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;
    }
}

The solution is pretty easy:解决方案非常简单:

First you need to implement the controller that will handle all error cases.首先,您需要实现将处理所有错误情况的控制器。 This controller must have @ControllerAdvice -- required to define @ExceptionHandler that apply to all @RequestMappings .此控制器必须具有@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");
    }
}

Provide exception you want to override response in @ExceptionHandler .@ExceptionHandler中提供要覆盖响应的异常。 NoHandlerFoundException is an exception that will be generated when Spring will not be able to delegate request (404 case). NoHandlerFoundException是当 Spring 无法委托请求时将生成的异常(404 情况)。 You also can specify Throwable to override any exceptions.您还可以指定Throwable来覆盖任何异常。

Second you need to tell Spring to throw exception in case of 404 (could not resolve handler):其次,您需要告诉 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);
    }
}

Result when I use non defined URL当我使用未定义的 URL 时的结果

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

UPDATE : In case you configure your SpringBoot application using application.properties then you need to add the following properties instead of configuring DispatcherServlet in main method (thanks to @mengchengfeng):更新:如果您使用application.properties配置 SpringBoot 应用程序,则需要添加以下属性,而不是在 main 方法中配置DispatcherServlet (感谢@mengchengfeng):

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

I know this is an old question but here is another way to configure the DispatcherServlet in code but not in the main class.我知道这是一个老问题,但这是另一种在代码中而不是在主类中配置DispatcherServlet的方法。 You can use a separate @Configuration class:您可以使用单独的@Configuration类:

@EnableWebMvc
@Configuration
public class ExceptionHandlingConfig {

    @Autowired
    private DispatcherServlet dispatcherServlet;

    @PostConstruct
    private void configureDispatcherServlet() {
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    }
}

Please not that this does not work without the @EnableWebMvc annotation.请注意,如果没有@EnableWebMvc注释,这将不起作用。

  1. Add this to your Properties file.将此添加到您的属性文件中。

     spring: mvc: throw-exception-if-no-handler-found: true web: resources: add-mappings: false
  2. In your @ControllerAdvice class add this:在您的@ControllerAdvice类中添加以下内容:

     @ExceptionHandler(NoHandlerFoundException.class) public ResponseEntity<Object> handleNoHandlerFound404() { return new ResponseEntity<>(HttpStatus.BAD_REQUEST);; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM