Configure ViewResolver with Spring Boot and annota

2020-01-24 20:26发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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