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