Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to add a jsp page in my Spring Boot service. My problem is that every time I try to go to that page I have this:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
Tue Apr 21 23:16:00 EEST 2015 There was an unexpected error (type=Not
Found, status=404). No message available
I have added the prefix and sufix into my application.properties:
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp
This is my controller class:
@Controller
public class MarkerController {
@RequestMapping(value="/map")
public String trafficSpy() {
return "index";
My Application class:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static Logger logger = Logger.getLogger(Application.class.getName());
public static void main(String[] args) {
logger.info("SPRING VERSION: " + SpringVersion.getVersion());
SpringApplication.run(Application.class, args);
And the index.jsp:
<!DOCTYPE html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
<h1>Hello, World!!!</h1>
<p>JSTL URL: ${url}</p>
</body>
</html>
And this is the src file structure:
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── internetprogramming
│ │ │ └── myserver
│ │ │ └── server
│ │ │ ├── Application.java
│ │ │ ├── config
│ │ │ │ └── DatabaseConfig.java
│ │ │ ├── controller
│ │ │ │ └── MarkerController.java
│ │ │ ├── dao
│ │ │ │ ├── MarkerDaoImplementation.java
│ │ │ │ └── MarkerDaoInterface.java
│ │ │ ├── Marker.java
│ │ │ └── service
│ │ │ ├── MarkerServiceImplementation.java
│ │ │ └── MarkerServiceInterface.java
│ │ ├── resources
│ │ │ └── application.properties
│ │ └── webapp
│ │ └── WEB-INF
│ │ └── jsp
│ │ └── index.jsp
–
–
<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>
Here is a working starter project - https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-jsp
–
–
–
–
–
–
–
–
This is working solution for me about White label error page : Cannot find view page(jsp)
At POM.xml, Make sure packaging is "war" and add tomcat/jasper dependencies
<packaging>war</packaging>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Add prefix/suffix at application.properties
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
** If you use Intellij, you must set Web Resource directories.
At Project Structure (ctrl+alt+shift+ S) > Facets > Select Web(your application) > Add(+) Web Resource Directories ( mine is ......\src\main\webapp)
** If you have multiple modules(At intellij),
Run> Edit configuration> Select springboot your application > Configuration tab> Working directory as $MODULE_WORKING_DIR$
–
Here is simple project with the minimum config: java 17 + spring boot 3.0.5 + JSP - https://github.com/uamaxua/spring-boot-jsp-sample
We were adding Spring Boot to our system in order to run it as executable application without standalone tomcat and also faces the 404 status during JSP initialization.
What should be done for fixing it:
a) Add dependencies to your pom file (WARNING: tomcat-embed-jasper must have compile scope not provided):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependencies>
b) Add spring boot maven plugin for building your application:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
c) Check that you are using *.war file for your artifact, not jar (because of JSP support limitation):
<packaging>war</packaging>
e) Now you should be able to run your spring boot application using maven plugin or with command line - java -jar /you/path/application-name.war:
f) But if you are using multi-module maven project and want to run spring boot application using IntelliJ Idea it is important to change "Working directory" -> $MODULE_DIR$:
UPDATE 24.02.2023:
If you are spring boot >= 2.4.0 then you need some extra configuration:
The DefaultServlet
provided by the embedded Servlet container is no longer registered by default (more information - here). But for JSP we need to register it again (with spring properties or java config):
server.servlet.register-default-servlet=true
@Bean WebServerFactoryCustomizer
enableDefaultServlet() {
return factory -> factory.setRegisterDefaultServlet(true);
Default Spring MVC no longer performs .* suffix pattern matching where a controller mapped to /person is also implicitly mapped to /person.*. As a consequence path extensions are no longer used to interpret the requested content type for the response — for example, /person.pdf, /person.xml, and so on (more information - here and here).
It is not recommended to use an extension in URL now. But if you need to use URL with suffix something like: http://localhost:8080/home.jsp
then you need to add such configuration:
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(false)
.useRegisteredExtensionsOnly(true)
.defaultContentType(MediaType.TEXT_HTML)
.mediaType("jsp", MediaType.TEXT_HTML);
And specify extension in your controller mapping:
@GetMapping("/home.jsp")
–
–
–
–
If you are using IDEA development tools, then you can try specifying
Configurations -> Configuration -> environment -> Working directory
The value in $MODULE_DIR$
my issue was Spring vesrion : I found that since 1.4.3 version and above stops supporting the embedded JSPs . So I change version to 1.4.1 , it's worked for me.
an other thing take off :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
it will not work with it .
In addition to the answers above the application needs to be deployed as war instead jar
<groupId>com.igt</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
to run
java -jar customer-0.0.1-SNAPSHOT.war
Also If you intend to start your application as a war or as an executable application, you need to share the customizations of the builder in a method that is both available to the SpringBootServletInitializer callback and the main method, something like
package com.igt.customer;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class CustomerApplication extends org.springframework.boot.web.support.SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CustomerApplication.class);
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
Please see
<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>
It may be not enough.
You must not miss this.
<packaging>war</packaging>
Otherwise when you build the package, you will get as a jar file and that does not have JSP nor the embedded tomcat.
See runable example and its explanation here https://www.surasint.com/spring-boot-jsp/
In case you've been struggling with this for a while and nothing helps, hear me out! I may help you! I've been there: I searched through the internet and was growing pretty desperate, but then I did this, and the problem vanished 🙌
You must have this Tomcat dependency
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Notice that it has a default scope. The default scope is compile
. It is important that you have this scope!
You should have these JSP/JSTL dependencies, both of them (at least, if you use something like a forEach
tag)!
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
Notice that they belong to the jakarta
package. In my case, it was important! Maybe, it may be important in your case too. Before I migrated my project to Spring Boot, I used javax
dependencies, specifically these two
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
When trying to open my home page with those dependencies, I received error 500
java.lang.ClassNotFoundException: javax.servlet.jsp.tagext.TagLibraryValidator
I added some more javax
dependencies to appease Spring a little
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
and it still didn't work in Spring Boot! This time, I received ClassCastException
because apparently Spring needed something specifically from the jakarta
package
java.lang.ClassCastException: class org.apache.taglibs.standard.tlv.JstlCoreTLV cannot be cast to class jakarta.servlet.jsp.tagext.TagLibraryValidator (org.apache.taglibs.standard.tlv.JstlCoreTLV and jakarta.servlet.jsp.tagext.TagLibraryValidator are in unnamed module of loader 'app')
MOST IMPORTANTLY! It appears you do need a webapp
package when working with JSP views! I thought that since it's Spring Boot, I don't need that directory and may place my views in the resources/templates
folder as HTML/Thymeleaf folks do. BIG MISTAKE! Even when my properties looked like this
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix= .jsp
or like this
spring.mvc.view.prefix=classpath:/templates/
spring.mvc.view.suffix= .jsp
in fact, any way you could imagine (I tried to describe the directory in all possible ways), I still got that pesky 404! Not before I created a webapp
directory had I managed to get rid of that problem
Notice that tiny bluish circle on the webapp
folder icon. I have a suspicion that it's important. As a matter of fact, I did try to create such a directory before, but it didn't have that little circle and moving my JSPs there had no effect on my 404. Why it didn't have that circle the first time? I don't know! But at any rate I suspect that the webapp
package should be in the same directory as your source root. In this case, it's the java
package. So since it's in the main
folder, your webapp
directory should be in the main
folder too
Fun fact! My favicon and CSS stylesheet are still in the resources
directory (that is, in the resources/static
directory)! Despite that, Spring has no problem figuring out where they are. So the webapp package is necessary only for your JSPs (perhaps, you can store CSSs and favicons there too, I didn't try it, but at least you don't have to)
Why it works this way with JSP? Search me! I have no idea at all! But it's what helped me and what you should apparently do too if you experience the same issue
You can get in touch with me and request the project's repo if that's something you need 👌
UPD: A quick note. Some folks maintain that you need to have a WAR package for JSP projects. It doesn't appear so! But keep it in mind anyway. If you did every thing I listed and it still doesn't work, tweaking that property may be a good thing to try 🤷♂️
UPD2: After I removed the WAR packaging setting, the little circle on the webapp
icon disappeared. But the page still opens! So since you apparently don't need WAR packaging, you also shouldn't be concerned about the blue circle. I take that back! Or maybe, the circle has nothing to do with WAR at all as I briefly returned that property and clean-installed the project, and it didn't appear again 🤷♂️
UPD3: By the way, that underlining never went away. But it's okay! It works nonetheless
Spring MVC offers no default (fall-back) error page out-of-the-box. The most common way to set a default error page has always been the SimpleMappingExceptionResolver
(since Spring V1 in fact). However Spring Boot also provides for a fallback error-handling page.
At start-up, Spring Boot tries to find a mapping for /error
. By convention, a URL ending in /error
maps to a logical view of the same name: error
. Generally this view maps in turn to the error.html
Thymeleaf template. (If using JSP, it would map to error.jsp
according to the setup of your
InternalResourceViewResolver).
Spring Boot will automatically use and configure Thymeleaf as the view rendering engine, as long as it's on the classpath.
Thymeleaf with Maven:
Make sure you have Maven 3 installed with the following command: mvn --version. Navigate to the directory you want to create your project in and execute Maven archtetype:
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=pl.codeleak.demos.sbt -DartifactId=spring-boot-thymeleaf -interactiveMode=false
The above command will create a new directory spring-boot-thymeleaf. Now you can import it to your IDE.
The next step is to configure the application. Open pom.xml and add a parent project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.1.8.RELEASE</version>
</parent>
Values from the parent project will be the default for this project if they are left unspecified.
The next step is to add web dependencies. In order to do so, I firstly removed all previous dependencies (junit 3.8.1 actually) and added the below dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
Now, wait a second until Maven downloads the dependencies and run mvn dependency:tree to see what dependencies are included.
The next thing is a packaging configuration. Let's add Spring Boot Maven Plugin:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Thymeleaf with Gradle:
To put Thymeleaf on the classpath use
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
in the gradle build file (using the relevant maven dependency is straightforward).
In your case in order to display the index.jsp
view (in accordance to the controller you are using), you need to place it under src/main/resources/templates/
.
If no mapping from /error to a View can be found, Spring Boot defines its own fall-back error page - the so-called Whitelabel Error Page
(a minimal page with just the HTTP status information and any error details, such as the message from an uncaught exception).
–
You can use thymeleaf with jsp but you have to write:
spring.thymeleaf.excluded-view-names=#jsp file without extension
in application.properties file
For spring-boot, Jsp templates or Thymeleaf templates mapping of spring MVC mapping prefix into classpath.
Ex. /views/some_path needs to be located in the project
src/main/resources/META-INF/resources/views/some_path
Thymeleaf templates work also in URL-based path file:///some_path
Jsp templates don't work in URL-based path file:///some_path