web-dev-qa-db-fra.com

Spring Boot Rest - Comment configurer 404 - ressource non trouvée

J'ai obtenu un service de repos de démarrage de printemps. Lorsque le chemin est erroné, il ne renvoie rien. Aucune réponse. En même temps, il ne génère pas non plus d'erreur. Idéalement, je m'attendais à une erreur 404 introuvable.

J'ai un GlobalErrorHandler

@ControllerAdvice
public class GlobalErrorHandler extends ResponseEntityExceptionHandler {

}

Il existe cette méthode dans ResponseEntityExceptionHandler

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

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

J'ai marqué error.whitelabel.enabled=false dans mes propriétés

Que dois-je faire d'autre pour que ce service renvoie une réponse 404 introuvable aux clients

J'ai fait référence à beaucoup de discussions et je ne vois pas ce problème rencontré par personne.

Ceci est ma principale classe d'application

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

La solution est assez simple:

First vous devez implémenter le contrôleur qui gérera tous les cas d'erreur. Ce contrôleur doit avoir @ControllerAdvice - requis pour définir @ExceptionHandler qui s'appliquent à tous @RequestMappings.

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

Indiquez l'exception à laquelle vous souhaitez remplacer la réponse dans @ExceptionHandler. NoHandlerFoundException est une exception qui sera générée lorsque Spring ne pourra pas déléguer de requête (cas 404). Vous pouvez également spécifier Throwable pour remplacer toutes les exceptions.

Second vous devez dire à Spring de lever l'exception en cas de 404 (impossible de résoudre le gestionnaire):

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

Résultat lorsque j'utilise une URL non définie

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

UPDATE : Si vous configurez votre application SpringBoot à l'aide de application.properties alors vous devez ajouter les propriétés suivantes au lieu de configurer DispatcherServlet dans la méthode principale (grâce à @mengchengfeng):

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

Je sais que c'est une vieille question mais voici une autre façon de configurer le DispatcherServlet dans le code mais pas dans la classe principale. Vous pouvez utiliser une classe @Configuration Distincte:

@EnableWebMvc
@Configuration
public class ExceptionHandlingConfig {

    @Autowired
    private DispatcherServlet dispatcherServlet;

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

Veuillez noter que cela ne fonctionne pas sans l'annotation @EnableWebMvc.

1
Alternatic