Spring Boot. Personalizar el json de error 404 y Swagger

En el proyecto en el que estoy trabajando ahora tenemos una API de servicios Rest hecha con Spring Boot y documentada usando Swagger. Existe una clase anotada con @RestControllerAdvice para personalizar la respuesta de error. He observado que cuando sucede un error 404 no se está ejecutando el método correspondiente por lo que, el JSON de error retornado, tiene el formato por defecto de Spring. Para que esto no suceda.

En el fichero application.properties

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

Implementar @RestControllerAdvice

@RestControllerAdvice
public class MyControllerAdvice {

    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<?> handleControllerException(HttpServletRequest request,
                                                       NoHandlerFoundException ex) {
        LOGGER.debug("handleControllerException. message: {}", ex.getMessage());
        // Return custom response entity
    }
}

Con esto ya responde con el formato de JSON que esperábamos.

Hacer funcionar Swagger UI

Al añadir la propiedad spring.resources.add-mappings esta solución vemos que deja de funciona Swagger UI. Da este error:

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

El problema es que el autoconfigurador mvc de spring mapea recursos por defecto que son los que utiliza Swagger para mostrar su página web.

Finalmente copio el código del autoconfigurador pero hago que en lugar de aplicar a todas las url "/**" aplique sólo a "/swagger-ui.hml" tal y como se puede ver en el siguiente código:

@Configuration
@EnableWebMvc
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");

        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations(getStaticLocations());
    }

    private String[] getStaticLocations() {
        return new String[]{
                "/",
                "classpath:/META-INF/resources/",
                "classpath:/resources/",
                "classpath:/static/",
                "classpath:/public/"
        };
    }
}

Fuente

Deja un comentario