After we upgraded from Spring Boot 1.4.0 to 1.5.3 our web application does not throw the NoHandlerFoundException anymore. Configuration looks like the following:
in application.properties:
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
the corresponding exception controller:
@ControllerAdvice
@EnableWebMvc
public class ExceptionController
{
// works
@ExceptionHandler(AccessDeniedException.class)
public String handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request) {
return "403";
}
// doesn't work anymore
@ExceptionHandler(NoHandlerFoundException.class)
public String handleNotFoundError(NoHandlerFoundException ex, HttpServletRequest request) {
return "404";
}
}
We had no problems with Spring 1.4.0 but it stopped working in 1.5.3. Why is the exception not thrown anymore?
Did you have @EnableWebMvc with both 1.4 and 1.5? I would expect it to turn off the auto-configuration of Spring MVC making spring.mvc.throw-exception-if-no-handler-found=true have no effect
Unfortunately, omitting @EnableWebMvc has no effect.
Something that is, I think, the same as you are doing works for me with both 1.4.6 and 1.5.3. Can you please provide a small sample that reproduces the problem you're seeing? Something that works with 1.4.0 but fails with 1.5.3 would be ideal.
While preparing a sample application we've found the culprit:
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/resources/",
"classpath:/static/", "classpath:/public/" };
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
}
}
Replacing the URl pattern with the subfolder containing the static resources spring.mvc.throw-exception-if-no-handler-found=true have the desired effect. Thank you.
By default, the聽DispatcherServlet聽does not throw a聽NoHandlerFoundException.聽You need to enable that:
I use Spring Boot 1.5.4.RELEASE:
I added
@EnableWebMvc
and in my prop file I added
server.error.whitelabel.enabled: false
spring.mvc.throw-exception-if-no-handler-found: true
@Berg-it adding @EnableWebMvc should totally switch off Spring Boot's auto-configuration for Spring MVC - so all spring.mvc.* configuration properties will be ignored. See the reference documentation on that.
@bclozel: You are right! I'll see how can I active this property. Thnak you
Sorry to re-open this issue, but I am experiencing a very closely related problem.
I am developing a small webapp with Spring Boot, HTML controllers and Thymeleaf.
I am not using @EnableWebMvc (and I would prefer not to use it).
What I would like to do is both these two things :
Is there a way to accomplish this?
My issue is basically the same as this StackOverflow page: https://stackoverflow.com/questions/39973945/no-handler-found-exception-and-static-recources-in-spring-boot
Thanks.
@AndRossi the answer on that SO thread is right.
When the resource handler doesn't find a static resource to serve, it's not delegating to the next handler in line, but rather responding with an HTTP 404. The only way to achieve what you want is to map your static resources under a specific sub-path like /static configure the spring.mvc.throw-exception-if-no-handler-found configuration property. That exception will be sent as long as the static resources handler is not involved.
Hi @bclozel, thank you for the lightning-fast answer!
Unfortunately I have tried that answer but it does not seem to work in my scenario.
This is what my configuration currently looks like:
spring.thymeleaf.cache:false
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
spring.datasource.url=jdbc:postgresql://localhost:5432/db-name
spring.datasource.username=...
spring.datasource.password=...
spring.jpa.properties.hibernate.default_schema=db.name
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.hibernate.ddl-auto = update
spring.mvc.throw-exception-if-no-handler-found=true
spring.mvc.static-path-pattern=/**
spring.resources.static-locations=classpath:/static/
In my environment, it does allow the client to get the static resources, but missing URIs do not throw any exceptions :/
You're mapping everything with your static path pattern, so this behavior is expected. For further questions, please use StackOverflow.
I'm sorry, I asked again,@bclozel, @AndRossi ,Set by the @androssi method, getting static resources is fine in my environment, but the lack of uris does not throw NoHandlerFoundException
I want to do both at the same time:
But the existing configuration has not been solved
application.yaml
spring:
resources:
static-locations: "classpath:/static/"
mvc:
throw-exception-if-no-handler-found: true
static-path-pattern : "/**"
ControllerExceptionAdvice
@ControllerAdvice
public class ControllerExceptionAdvice {
@ExceptionHandler(NoHandlerFoundException.class)
public void noHandlerFoundExceptionExceptionResolvers(HttpServletResponse response) throws Exception {
writeResponse(response, JsonResult.JsonResult(false, "resources lost!", 404));
}
private void writeResponse(HttpServletResponse response, JsonResult message) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write(Json.encode(message) );
}
}
@zhangjiaxin281 same answer, actually.
The NoHandlerFoundException is thrown when no HandlerMapping has been found; HandlerMapping as in RequestMappingHandlerMapping or SimpleHandlerMapping, not as "an annotated controller method that handles the request".
In your case, when an incoming request comes in at "/something" and no controller handler is detected with RequestMappingHandlerMapping , the next registered HandlerMapping instances are considered. Since you've registered static resource handling on /**, this means that it will handle /**, so the NoHandlerFoundException will never be thrown.
Now the static resources handling might respond with an HTTP 404, but this is an expected response for such a handler. Either the static resource is there and we respond with it, or we respond with a 404.
Most helpful comment
While preparing a sample application we've found the culprit:
Replacing the URl pattern with the subfolder containing the static resources
spring.mvc.throw-exception-if-no-handler-found=truehave the desired effect. Thank you.