64

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
Nick Spacek
  • 4,717
  • 4
  • 39
  • 42

20 Answers20

112

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.

Nick Spacek
  • 4,717
  • 4
  • 39
  • 42
  • 3
    You just made my day! This helped me - even though my issue was slightly different - Spring wasn't even **finding** my .jsp files in `/src/main/resources/webapp/WEB-INF/pages`. Thank you so much! – Andrei Bârsan May 17 '14 at 12:31
  • Had the same issue as Adrei, it kept complaining about circular dependencies until I added the jar. – Mike R Aug 24 '14 at 22:46
  • This only will not work. Servlet 3.0 expect jsp to be included in META-INF folder. See this sample application https://github.com/kamoor/spring-boot-sample – kamoor Dec 30 '14 at 04:05
  • 1
    @kamoor I have never seen JSPs in the META-INF and I am quite sure the Servlet 3.0 API does not specify that as the location for JSP files; can you reference where in the spec it says that? Every JSP application I have seen has its JSPs in the WEB-INF. Since you are using 3.0 and Spring Boot, you should consider using Java Configuration instead of XML! – Nick Spacek Dec 30 '14 at 11:57
  • @NickSpacek I was seeing many SOF questions and servlet 3.0 spec, none of them specifically says what needs to happen for JSPs inside jar. See section 10.10 in http://download.oracle.com/otn-pub/jcp/servlet-3.0-fr-oth-JSpec/servlet-3_0-final-spec.pdf it talks only about resources but I see JSP also works that way. My sample app is in https://github.com/kamoor/spring-boot-sample. Have you got above location (webapp/WEB-INF/..) working while packaging as jar? Could you move that jar to another folder or machine and try to run it? – kamoor Dec 30 '14 at 13:59
  • Haha you asked and answered the question exactly the same time. Nice technique for gaining points :) Will try myself :D – Storm Oct 08 '15 at 08:00
  • 1
    @Storm It's a checkbox option when posting a question (says something like share your knowledge with the community wiki-style). I think you perhaps do not gain points? Not sure. Regardless, seems like a lot of other people have had the same problem! – Nick Spacek Oct 08 '15 at 11:46
  • +1 for this - worked for me with a barebones Spring Boot application that was just throwing back 404 errors for any pages I accessed. I'm also using a `src/main/resources/application.properties` file to define a couple `spring.view` properties. It's also listed in the POM for the sample JSP application, but I completely overlooked it: https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp – Craig Otis Apr 27 '16 at 22:36
  • @NickSpacek had a same issue but it didn't work for me. I am using Jboss EAP 6.4. – michaeln peterson May 03 '16 at 12:17
  • @CraigOtis I tried using the sample JSP but it doesn't work for me. If I comment out the `provided` for `spring-boot-starter-tomcat` it will start up, but i get a 404 Not Found for `/` path. – barclay May 12 '16 at 21:25
  • why this path `webapp/WEB-INF/pages` not exist in my spring boot application I ony have `/src/main/resources` :( – Osama Al-Banna Feb 15 '17 at 16:23
24

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>
Sezin Karli
  • 2,517
  • 19
  • 24
  • @sezil Karil Could you help me on my issue. https://stackoverflow.com/questions/61359718/simple-spring-boot-jar-doesnt-work-except-build-target-folder – Sthita Apr 22 '20 at 10:11
16

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!

JaySon
  • 367
  • 5
  • 14
12

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>
Dan
  • 267
  • 2
  • 6
10

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'
Aravind Cheekkallur
  • 3,157
  • 6
  • 27
  • 41
9
  1. Make sure, spring-boot-starter-tomcat, tomcat-embed-jasper and jstl dependencies are in the pom.xml.
  2. Make sure the packaging type is war.
  3. If there are multiple modules (IntelliJ), go into Run -> Edit configuration -> Configuration, and select or put $MODULE_WORKING_DIR$ in the 'Working directory'.

That's it.

Askar
  • 544
  • 1
  • 6
  • 17
7

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

5

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 { ... }

Aarish Ramesh
  • 6,745
  • 15
  • 60
  • 105
3

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;
    }
}

from: Why does Spring MVC respond with a 404 and report "No mapping found for HTTP request with URI [...] in DispatcherServlet"?

granadaCoder
  • 26,328
  • 10
  • 113
  • 146
RoutesMaps.com
  • 1,628
  • 1
  • 14
  • 19
  • 1
    where i have to add reolver method ?? i think it should be in a class that extends WebMvcConfigurationSupport , am i right ? – Mohammad Mirzaeyan Mar 17 '17 at 16:31
  • 1
    Yes. Or in a class with the same meaning annotations: Configuration and EnableWebMvc I have updated example in my answer for this case. – RoutesMaps.com Mar 17 '17 at 19:25
2

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>
Crabigator360
  • 822
  • 10
  • 9
2

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;
    }

}
John Tribe
  • 1,407
  • 14
  • 26
2

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> 
abhijeet badale
  • 149
  • 1
  • 3
2

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
Mark
  • 5,994
  • 5
  • 42
  • 55
1

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>
Sandeep Kumar
  • 596
  • 5
  • 7
1

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";
    }
}
Surasin Tancharoen
  • 5,520
  • 4
  • 32
  • 40
1

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.

enter image description here

My solution:

  1. Move index.jsp into a subfolder called views.

    enter image description here

  2. 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>
    
  3. 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>
    
  4. Using the same base-package path as specified in dispatcher-servlet.xml, create controller that will return a ModelAndView.

    enter image description here

    package com.app.controller;
    
    @Controller
    @RequestMapping(value = "/")
    public class RootController {
    
        @RequestMapping(method = RequestMethod.GET)
        public ModelAndView homeGet() {
    
            return new ModelAndView("index", "message", "IT WORKS!!!");
        }
    
    }
    
  5. The syntax new ModelAndView("index", "message", "IT WORKS!!!") means that
    • dispatcher-servlet looks for a file called "/WEB-INF/views/" + "index" + ".jsp".
    • It compiles the jsp file, replacing all instances of ${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>
  1. Load the project into your Tomcat server, start it, and go to http://localhost:8080/[project name]/.

    enter image description here

Cameron Hudson
  • 3,190
  • 1
  • 26
  • 38
1

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

qwerty
  • 2,392
  • 3
  • 30
  • 55
0

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>
VNT
  • 934
  • 2
  • 8
  • 19
  • @Crimean.us - Springboot don't need the explicit configuration like your view resolver. Then what made the difference between spring MVC and boot? – VNT Apr 21 '17 at 10:15
0
<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>
jeff porter
  • 6,560
  • 13
  • 65
  • 123
0

Please consider, there are some JSP Limitations. You can not set the packaging of your pom to jar. Read this JSP Limitations

Askar
  • 544
  • 1
  • 6
  • 17