Reputation: 4773
I have a Spring Boot web application up and running using embedded Tomcat (the default). When it serves up JSP files as part of rendering the view I specified in my controller, the JSPs are not being rendered as such, and instead print out the contents. For example:
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>Test</body>
</html>
When the view is rendered in the browsers, the contents above are displayed, instead of the expected contents:
Test
Upvotes: 64
Views: 116607
Reputation: 6404
As seen Spring and Spring Boot has been changing, here is an up-to-date solution.
build.gradle
:
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.0.RELEASE'
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.0.35'
}
IndexController.java
looks as follows:
@Controller
public class IndexController {
@RequestMapping("/index")
public String index(Model model) {
model.addAttribute("name", "jancsi");
return "index";
}
}
WebConfig.java
:
@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Here, instead of using WebMvcConfigurerAdapter
, you should use WebMvcConfigurer
interface, and do not to forget to enalbe the default servlet hander.
And then the structure of folders of jsp files.
src/main/webapp
└── WEB-INF
└── views
└── index.jsp
Upvotes: 2
Reputation: 179
You need jsp compiler jar (tomcat-jasper) in class-path. Embedded tomcat does not come with it. Remove tomcat-embed-jasper.jar if added already and add below
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>9.0.1</version>
</dependency>
Upvotes: 3
Reputation: 574
spring-boot-starter-tomcat
, tomcat-embed-jasper
and jstl
dependencies are in the pom.xml.war
.$MODULE_WORKING_DIR$
in the 'Working directory'.That's it.
Upvotes: 9
Reputation: 574
Please consider, there are some JSP Limitations. You can not set the packaging
of your pom
to jar
. Read this JSP Limitations
Upvotes: 0
Reputation: 2512
For me with Spring Boot version 1.5.10.RELEASE, it worked on adding below maven dependencies.
Note: worked only on not providing the <scope>
for these two.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<!--<scope>provided</scope>-->
</dependency>
And providing below configuration in application.properties file
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
Upvotes: 1
Reputation: 1689
I resolved my issue when in addition to described before:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
added ViewResolver:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan
@EnableWebMvc
public class SpringServletConfig {
@Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
}
Upvotes: 3
Reputation: 3943
I had this problem and finally resolved it!
My problem was that I had been putting JSP code in my /WEB-INF/index.jsp
page. However, this page is served directly, without being processed by any servlet or controller. Therefore, it had no chance of being compiled.
My solution:
Move index.jsp
into a subfolder called views
.
Edit web.xml
so that it passes control of the root directory to the dispatcher servlet.
<!-- WEB-INF/web.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<display-name>18-655_lab_1</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Edit dispatcher-servlet.xml
to ensure that it's looking in the views
directory for files ending in .jsp
.
<!-- WEB-INF/dispatcher-servlet.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<mvc:annotation-driven />
<context:component-scan
base-package="com.app.controller" />
<mvc:default-servlet-handler />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
Using the same base-package
path as specified in dispatcher-servlet.xml
, create controller that will return a ModelAndView.
package com.app.controller;
@Controller
@RequestMapping(value = "/")
public class RootController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView homeGet() {
return new ModelAndView("index", "message", "IT WORKS!!!");
}
}
new ModelAndView("index", "message", "IT WORKS!!!")
means that
dispatcher-servlet
looks for a file called "/WEB-INF/views/" + "index" + ".jsp"
.${message}
with IT WORKS!!!
.Therefore, the final thing to do is to put ${message}
somewhere in our index.jsp
file.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>${message}</h1>
</body>
</html>
Load the project into your Tomcat server, start it, and go to http://localhost:8080/[project name]/
.
Upvotes: 1
Reputation: 7043
The reason is because you are using the annotation @RestController instead of @Controller
When you annotate a class with RestController, all methods annotated with @RequestMapping assume @ResponseBody semantics by default. In other words, your method #index is serializing the String /webapp/WEB-INF/index.jsp as JSON, instead of mapping its value to a view.
Like mentioned in one of the answers, it has to be
@Controller public class YourController { ... }
Upvotes: 6
Reputation: 951
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherSe rvlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I took the * off so it was just from web.xml
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherSe rvlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Upvotes: 0
Reputation: 727
I think you missed some configuration because it is easy to integrate JSP just follow below steps
1 - tomcat-embad-jasper dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
2 - Add below configuration is application.properties
spring.mvc.view.prefix: /
spring.mvc.view.suffix: .jsp
That's it still have some doubt then check it out below link
Spring Boot and JSP Integration
Upvotes: 7
Reputation: 5850
If you want to use 1.5.8.RELEASE or similar, then, runable example and its explanation is in here https://www.surasint.com/spring-boot-jsp/
You just need this in pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.boot spring-boot-starter-parent 1.5.8.RELEASE
<groupId>com.surasint.example</groupId>
<artifactId>spring-boot-02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JSP -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- jstl for jsp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
And this in application.properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
Then you keep your jsp in the /WEB-INF/jsp/ folder.
This is the controller.
package com.surasint.example.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Date;
import java.util.Map;
@Controller
public class TestController {
@GetMapping("/testjsp")
public String list(Map<String, Object> model) {
model.put("this_time",new Date().toString());
return "testjsp-view";
}
}
Upvotes: 1
Reputation: 702
Sometimes tomcat-embed-jasper not available so need to remove provided from the maven dependency of tomcat-embed-jasper.
eg.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--scope>provided</scope-->
</dependency>
Upvotes: 1
Reputation: 1632
Full gradle setup for Spring-Boot with Spring-MVC and with embedded Tomcat server:
build.gradle
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
//WEB-MVC
compile 'org.springframework.boot:spring-boot-starter-web:1.5.8.RELEASE'
compile 'org.apache.tomcat.embed:tomcat-embed-jasper:9.0.1'
compile 'javax.servlet:jstl:1.2'
App.class
@SpringBootApplication
public final class App {
public static void main(final String[] args) {
new SpringApplicationBuilder(App.class)
.build(args)
.run();
}
@Bean
public ViewResolver viewResolver() {
final InternalResourceViewResolver r = new InternalResourceViewResolver();
r.setPrefix("/WEB-INF/jsp/");
r.setSuffix(".jsp");
return r;
}
}
Upvotes: 2
Reputation: 1032
Just change the dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
to
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Upvotes: 3
Reputation: 974
I faced the issue like printed the jsp file name in the browser instead of its contents.
By adding the below snippet for jsp page rendering in pom.xml , it renders properly.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Upvotes: 0
Reputation: 377
For me worked the same like Dan mentioned. Removing the provided scope.
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
Thanks guy's!
Upvotes: 16
Reputation: 267
Worked for me too but, I had to remove
<scope>provided</scope>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Upvotes: 12
Reputation: 4773
Make sure that your pom.xml
specifies the Tomcat JSP dependency as follows:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
It seems that embedded Tomcat treats the JSP rendering as optional.
As mentioned below, this JAR is sometimes necessary as well:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>provided</scope>
</dependency>
(I added provided since this JAR should be included by the servlet container.
Upvotes: 113
Reputation: 3205
Better you can use gradle (which is catching up over Maven). Use this dependency in build.gradle file.
//Required dependency for JSP
providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
Upvotes: 10
Reputation: 2525
You will need not one but two dependencies (jasper and jstl) in your pom.xml
for this to work.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
</dependencies>
Upvotes: 24