38

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.

Community
  • 1
  • 1
otognan
  • 1,736
  • 3
  • 16
  • 20
  • 1
    Setting view resolver prefix and suffix can be simplified by putting these properties in application.properties file: spring.mvc.view.prefix=/WEB-INF/ spring.mvc.view.suffix=.html – luke Oct 04 '16 at 21:46

4 Answers4

52

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.

Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
  • Thank you! This does resolve the error. However somehow documentation http://docs.spring.io/spring/docs/current/spring-framework-reference/html/view.html somehow gives the impression that spring can handle html and jsps out of the box. It looks like falling back to default servlet is described as a possibility but not the normal way of serving jsps. What am I missing? – otognan Apr 30 '15 at 05:43
  • Also the similar error with web.xml is usually resolve itself after changing DispatcherServlet mapping. Why is annotation configuration different? What am I missing? – otognan Apr 30 '15 at 05:50
  • 4
    Compared to adding "tomcat-embed-jasper", which fixes the problem for me, your solution leads to the .jsp being displayed "raw": It's a raw output of the jsp file including all tags and not rendered as html. – ASA Sep 16 '15 at 22:06
  • 2
    `WebMvcConfigurerAdapter` is deprecated since Spring 5; use `WebMvcConfigurer` as described here: https://stackoverflow.com/questions/47552835/the-type-webmvcconfigureradapter-is-deprecated – max3d Jun 12 '18 at 14:46
  • WebMvcConfigurerAdapter is depreciated you might want to implement WebMvcConfigurer – Rudy Jan 09 '19 at 14:23
18

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
kiyah
  • 1,502
  • 2
  • 18
  • 27
Piyush Upadhyay
  • 427
  • 4
  • 12
15

After investigating more I discovered an alternative solution that works without adding configureDefaultServletHandling method. You need to add an embedded tomcat jsp engine to build.gradle:

compile("org.apache.tomcat.embed:tomcat-embed-jasper")

As opposed to configureDefaultServletHandling method this solution works not only with plain html but also with jsp.

All solutions are available at: https://github.com/driver-pete/spring-mvc-example This solution is available on master. Biju's solution is on DefaultServletHandling_solution branch.

otognan
  • 1,736
  • 3
  • 16
  • 20
  • 1
    thank you very much :) i had a source code based on an old spring mvc frameworks , and i wanted to migrate it to new spring mvc based on spring boot for better and easy development and deployment . You saved me a lot of time – kaveh.n Aug 03 '16 at 05:25
0

If you are using spring above 5.0, then use org.springframework.web.servlet.view.InternalResourceViewResolver instead of org.springframework.web.servlet.InternalResourceViewResolver in your bean definition

krishna Prasad
  • 3,541
  • 1
  • 34
  • 44