9

I have a webapp using Spring-MVC built with Maven. When I generate the JAR file the app start just fine. The controller is execute but when I reach this part:

@RequestMapping(value = "/test-block", method = RequestMethod.GET)
public ModelAndView block(Model model) {
    return new ModelAndView("templates/test-block");
}

I get this error:

There was an unexpected error (type=Not Found, status=404).
/WEB-INF/templates/test-block.jsp

Note that debugging or running in the IDE works fine.

My folder:

src
|--main
   |--java
      |--com.xxx // sources
      webapp
      |--WEB-INF
         |--templates
            |--*.jsp // jsp files
      resources
      |--application.properties

My application properties:

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

I checked the generated JAR file and I can't see WEB-INF anywhere.

edit:

pom file:

    <packaging>war</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
The Bitman
  • 1,279
  • 1
  • 11
  • 25
Mariano L
  • 1,809
  • 4
  • 29
  • 51
  • Shouldn't you be generating a .war file? – Nicholas K Oct 05 '18 at 17:20
  • I wanted a standalone jar file. But tried doing a war file and now that folder is included. Weird – Mariano L Oct 05 '18 at 17:24
  • Use a request mapper which returns a simple String value (view name) or set the model name and value at the constructor of the `ModelAndView` object. – The Bitman Oct 05 '18 at 18:41
  • A single jar file is not a stand alone web application. Just a module which you can reuse in web applications if you include them into the classpath of a web app packaged into a WAR/EAR file. – The Bitman Oct 05 '18 at 18:46
  • @TheBitman yes, Spring Boot applications are typically bundled as a single jar file, that contains an embedded web server. – JB Nizet Oct 05 '18 at 19:12
  • 1. There is no such thing as a WEB-INF directory when you use jar files. 2. You need to avoid using JSPs, or at the very least read and understand the warnings about its usage in the documentation: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-jsp-limitations – JB Nizet Oct 05 '18 at 19:14
  • @JBNizet "I have a webapp using Spring-MVC built with Maven." Spring-boot is just mentioned as a tag and I did not notice it. – The Bitman Oct 05 '18 at 19:21

3 Answers3

7

You should create a .war rather than a .jar for a web application and you will see the WEB-INF folder.

Also change

spring.mvc.view.prefix=/WEB-INF/ to spring.mvc.view.prefix=/WEB-INF/templates and

ModelAndView("templates/test-block") to ModelAndView("test-block") to address the 404 error.

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
  • 2
    The modelAndView is actually working. I was getting the 404 because the WEB-INF wasn't included in the JAR so test-block.jsp was missing. Created a WAR and now all the files are included. Thanks! – Mariano L Oct 05 '18 at 18:53
3

Reference the Spring Boot documentation on serving static content.

Of note:

By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so that you can modify that behavior by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.

...

You can also customize the static resource locations by using the spring.resources.static-locations property (replacing the default values with a list of directory locations).

...

Do not use the src/main/webapp directory if your application is packaged as a jar. Although this directory is a common standard, it works only with war packaging, and it is silently ignored by most build tools if you generate a jar.

So, what you're seeing is the expected behavior. You can either move your templates to one of the expected locations, customize the default locations, or use war packaging.

The Gilbert Arenas Dagger
  • 12,071
  • 13
  • 66
  • 80
0

Spring boot looks for resources folder for web pages. Webapp folder is not in classpath of spring boot app. You need to use a maven plugin to copy your webapp folder into the jar/war file. It works in IDE since it knows exactly where to find the web pages.

Yan Burtovoy
  • 198
  • 1
  • 2
  • 15