Spring boot - Unable to resolve jsp views
Solution 1
Spring Boot has limited support for JSP, because of its use of an embedded servlet container. From the Spring Boot reference documentation:
When running a Spring Boot application that uses an embedded servlet container (and is packaged as an executable archive), there are some limitations in the JSP support.
- 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.
- Jetty does not currently work as an embedded container with JSPs. There is a JSP sample so you can see how to set things up.
Start by making your app an executable war, and make sure that you use Tomcat (check the log when you start the application). Unless you explicitly have stated you Jetty should be included, you are using Tomcat since that is provided by default. Alternatively, try change your view technology, which probably requires more initial work, but can significantly reduce the turnaround time during development, see Hotswapping.
Solution 2
I ran into this problem recently while upgrading an old project that needed to have jsps
as the view technology with tomcat
as an embedded servlet-container
. Caveat: Pick an alternative templating engine, and avoid jsps if you can. But if you can't avoid jsps, and your application is not able to resolve them, at the time of this writing (spring-boot 2.x.x), ensure the following:
- Ensure that application packaged as a war and not a jar. Although it is not impossible to get jsps to work with a jar packaging, it is a little complicated due to certain limitations. You could just run them with a war package in a server or container just fine like:
java -jar war-filename.war
- Verify that your controllers have the
@Controller
annotation BUT NOT the annnotation@EnableWebMvc
. That's because you are usingspring-boot
to configure WebMVC for you. - Is your controller being scanned and injected as a component? If you have defined your controllers in a different package, maybe you are missing a
@ComponentScan
annotation? - Are you jsps located and configured correctly? For example, let's say your jsps are located in /src/main/webapp/WEB-INF/jsp/, then your
application.properties
should have something like so:spring.mvc.view.prefix: /WEB-INF/jsp/ spring.mvc.view.suffix: .jsp
Also, since you are using spring-boot, there is no need for your Application
to extend the SpringBootServletInitializer
. It will work too, but to keep it simple, all you need is a class like below:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
FYI, the minimal set of dependencies needed are mentioned below (Maven Example):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<!-- spring-boot dependencies below -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- jstl and jsp compilation support below -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
Balasubramanian
Updated on June 24, 2022Comments
-
Balasubramanian almost 2 years
I am trying to build a basic MVC app using Spring boot with Hibernate as ORM and MySql as Database. The problem that I am facing is that the jsp views are not getting resolved.
I get a 404 error when I try to fetch the registration form using a GET request with the following URL:
http://localhost:9000/users/register/
This is the set-up that I have in my application.
Directory structure:
-src -main -java -com ApplicationStart.java -controllers UserController.java -repositories UserRepository.java -webapp -WEB-INF -jsp register.jsp -resources application.properties
UserController:
@RestController public class UserController { private UserRepository userRepository; @Autowired public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @RequestMapping(value = "/users/register", method = RequestMethod.GET) public String Register() { return "register"; } }
Application.properties:
server.port: 9000
spring.datasource.url: jdbc:mysql://localhost/Contacts
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.datasource.username: root
spring.datasource.password:
spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp
POM.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.1.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- HIBERNATE --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> </dependency> <!-- MYSQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> </dependencies>
MAIN CLASS
@ComponentScan @Configuration @EnableAutoConfiguration public class ApplicationStart { public static void main(String[] args) { SpringApplication.run(ApplicationStart.class, args); } }
This is the current setup of my application. Any help on how to resolve the issue is much appreciated.
Please comment if more information is required.
Thanks-