Configure ViewResolver with Spring Boot and annotations gives No mapping found for HTTP request with URI error

I'm trying to make "hello world" application with gradle, spring boot and spring mvc with the simplest view resolver and html.

I started from the thymeleaf spring boot example and I just wanted to remove thymeleaf to make a simpler mvc application using pure html and InternalResourceViewResolver. I have a single greeting.html I want to serve which is located at src/main/webapp/WEB-INF. When I run the app I get

No mapping found for HTTP request with URI [/WEB-INF/greeting.html] in DispatcherServlet with name 'dispatcherServlet'

This is a common error and there are a lot of answers on the web but nothing seems to help.

Here is my Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Here is my GreetingController.java

@Controller
public class GreetingController {
    @RequestMapping("/greeting")
    public String greeting() {
        return "greeting";
    }
}

Here is my MvcConfiguration.java

@Configuration
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".html");
        return resolver;
    }
}

I run it with gradle bootRun

Here is the repo with the code: https://github.com/driver-pete/spring-mvc-example

Here are some more clues:

  • Thymeleaf view resolving works fine
  • InternalResourceViewResolver resolves to the right path
  • WEB-INF and greeting.html seems to be present in the war file
  • I do not have jsp or jstl so I do not miss those jars as some might suggest

My hypothesis is that dispatcher servlet somehow get configured to serve on /* instead of / like here and everywhere. However I don't have web.xml so those advices do not apply here. I see a lot of examples how to configure dispatcher servlet programmatically but I want to keep my app at minimum and I suspect that spring boot is supposed to configure it ok since it works fine with thymeleaf.


You only need to enable the default servlet, this is done by adding the following to your MvcConfiguration:

@Configuration
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/");
        resolver.setSuffix(".html");
        return resolver;
    }

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }    
}

Essentially what is happening is Spring does not know how to handle the handling of such content natively(could be a jsp say), and to this configuration is the way to tell it to delegate it to the container.


View resolver can also be configured in application.properties file of Spring-Boot web applications, something like below:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp