Search code examples
mavenjspspring-mvcspring-boot

By default, where does Spring Boot expect views to be stored?


I'm experimenting on re-writing my configuration-heavy, vanilla Spring MVC project using Spring Boot. I started a brand new Spring Boot project in IntelliJ using the Spring Boot Initiaizer and I'm going the route of minimal Java-based configuration. Lots of tutorials point out that the default main class generated is sufficient and that @SpringBootApplication has everything included. I got a sample REST Controller to work and return a serialized object as JSON, but it appears getting a view to show is proving difficult. My structure is as follows, with everything default other than the webapps directory which I created.

src
`-main
   `-java
   `-resources
     `-static
     `-templates
   `-webapp
     `-WEB-INF
        `-home.jsp

The controller is plain simple.

@Controller
public class ViewMaster {
    @RequestMapping("/home")
    public String home() {
        return "home";
    }
}

Without any configuration, I'd like to know where Spring Boot expects the views to be stored and with what extension (html?). I've also tried to include the following in application.properties but I still get a 404 error. Moving the WEB-INF directory or just the html file around in resources didn't help either.

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

I've also tried including these dependencies in my pom.xml without any effect.

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>

I must be missing something painfully obvious here so appreciate if someone can point that out!


Solution

  • The Solution

    I found the answer via trial-and-error, which turned out rather annoying. I hope someone can correct me if this conclusion is wrong, but it appears that Spring Boot does not like the string WEB-INF. I renamed the WEB-INF directory to view and changed the application.properties to the following and the view loaded successfully.

    spring.mvc.view.prefix=/view/
    spring.mvc.view.suffix=.jsp
    

    Additional Findings

    The objective of this exercise was to create a working example of a minimal, Java-based configuration so I continued minimalising the setup. I then found that lots of advice dished out on multiple SO threads and forums did not help. @JBNizet provided a link in his comment to the Spring Boot docs which lists a very salient point that no one has mentioned: JSPs simply do not play well with Spring Boot as it has limitations depending on the embedded container chosen. With that in mind, I decided to try replacing JSPs with ThymeLeaf templates.

    My new working config removes the need for these:

    • No need to add application.properties: spring.mvc.view.prefix + spring.mvc.view.suffix
    • No need to change the packaging type from jar to war
    • No need to modify main class
    • No need to add pom.xml dependencies for
      • org.springframework.boot / spring-boot-starter-tomcat
      • org.springframework.boot / tomcat-embed-jasper
      • javax.servlet / jstl

    So just the default Spring Boot template and 2 ThymeLeaf dependencies with the views named as ViewName.html placed in src/main/resources/templates.

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring4</artifactId>
    </dependency>