Spring boot use resources templates folder with JSP templates instead of webapp folder?
According to the Maven documentation src/main/resources
will end up in WEB-INF/classes
in the WAR.
This does the trick for Spring Boot in your application.properties
:
spring.mvc.view.prefix = /WEB-INF/classes/templates
spring.mvc.view.suffix = .jsp
If you prefer Java configuration this is the way to go:
@EnableWebMvc
@Configuration
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setPrefix("/WEB-INF/classes/templates/");
bean.setSuffix(".jsp");
return bean;
}
}
Update with a full example
This example was based on Spring's initializer (Gradle project with "Web" dependency). I just added apply plugin: 'war'
to the build.gradle
, added/changed the files below, built teh project with gradle war
and deployed it to my application server (Tomcat 8).
This is the directory tree of this sample project:
\---src
+---main
+---java
| \---com
| \---example
| \---demo
| ApplicationConfiguration.java
| DemoApplication.java
| DemoController.java
|
\---resources
+---static
\---templates
index.jsp
ApplicationConfiguration.java: see above
DemoApplication.java:
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoApplication.class, args);
}
}
DemoController.java:
@Controller
public class DemoController {
@RequestMapping("/")
public String index() {
return "index";
}
}
index.jsp:
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
Official information:
Resource handling:
Links to resources are rewritten at runtime in template, thanks to a ResourceUrlEncodingFilter, auto-configured for Thymeleaf and FreeMarker. You should manually declare this filter when using JSPs. source
Supported template engine
As well as REST web services, you can also use Spring MVC to serve dynamic HTML content. Spring MVC supports a variety of templating technologies including Thymeleaf, FreeMarker and JSPs.
[...]
JSPs should be avoided if possible, there are several known limitations when using them with embedded servlet containers.
[..]
When you’re using one of these templating engines with the default configuration, your templates will be picked up automatically from src/main/resources/templates.
source
Spring boot JSP limitations
- With Tomcat it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to a standard
container (not limited to, but including Tomcat).- An executable jar will not work because of a hard coded file pattern in Tomcat.
- With Jetty it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to any standard container.
- Undertow does not support JSPs.
- Creating a custom error.jsp page won’t override the default view for error handling, custom error pages should be used instead.
source
Technical change
Tell spring boot to from where to load the JSP files
. In application.properties
set
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
source
Sample spring boot with JSP
In case you do want to use JSP
with spring boot here are two examples:
https://github.com/spring-projects/spring-boot/tree/v1.5.9.RELEASE/spring-boot-samples/spring-boot-sample-web-jsp
https://github.com/joakime/spring-boot-jsp-demo
To summarize it, none of the suggested answers worked for me so far. Using a blank Spring boot starter project.
Somehow, something looks hardwired inside Spring or servlets so that JSP must be in /webapp
(or a subfolder). Unlike default thymeleaf templates which are looked up in /resources/templates
.
I tried all kind of changes, really a lot of different configurations, but wasn't able to modify that behavior. It just produced complexity and was unable to serve the JSPs anymore. So, bottom line, if you're using JSPs, just put them in /webapp
. It also works by addding zero configuration using a controller like:
@GetMapping("/foo")
public String serveFoo() {
return "relative-path-inside-webapp/foo.jsp";
}
On another note, by default, the /webapp
folder will also be hidden in the Spring Toolsuite, so you'll have to manually configure it as a "source folder".