6
votes

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-

3
try http://localHost:port/YourProjectName/users/registerSparkOn
Make sure your pom packaging is war and not jar.emeraldjava

3 Answers

7
votes

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.

1
votes

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 using spring-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>
0
votes

Agree with @code4kix, If all of this doesn't work, try adding below property in your application.properties file

spring.thymeleaf.enabled=false