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?

Comment From: wilkinsona

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

Comment From: Harown

Unfortunately, omitting @EnableWebMvc has no effect.

Comment From: wilkinsona

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.

Comment From: Harown

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.

Comment From: Berg-it

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

Comment From: bclozel

@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.

Comment From: Berg-it

@bclozel: You are right! I'll see how can I active this property. Thnak you

Comment From: AndRossi

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 : - make sure that an exception is thrown if no handlers are found - have my static resources available for the client

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.

Comment From: bclozel

@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.

Comment From: AndRossi

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 :/

Comment From: bclozel

You're mapping everything with your static path pattern, so this behavior is expected. For further questions, please use StackOverflow.

Comment From: zhangjiaxin281

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: - If the handler cannot be found, be sure to throw an exception - Provide my static resources to customers

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

}

https://github.com/zhangjiaxin281/testNoHandler.git

Comment From: bclozel

@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.

Comment From: NikhilAdsul

Can anyone help me for that i am getting The type NoSuchRequestHandlingMethodException is deprecated. and error: package org.springframework.web.servlet.mvc.multiaction does not exist

in spring MVC application. with spring version 5.7.2

Comment From: bclozel

@NikhilAdsul this doesn't seem related at all. Could you try asking on StackOverflow? You should add more information as well: a complete stacktrace, your build file (gradle or maven) at a minimum.

Comment From: NikhilAdsul

Can anyone help me for that i am getting The type NoSuchRequestHandlingMethodException is deprecated. and error: package org.springframework.web.servlet.mvc.multiaction does not exist

in spring MVC application. with spring version 5.7.2

ok