Spring MVC Controller jsp file not found - spring-boot

I am creating a simple demo web for training purposes. The web displays the static content index.html correctly but whenever I try to route to /greeting url (specified by my controller) I get 404 error as showed below
However My code structure is the following
And the applicaiton.properties fiels is configured:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
My controller is also defined:
package com.pluralsight.conference.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Map;
#Controller
public class GreetingController {
#GetMapping("greeting")
public String greeting(Map<String,Object> model) {
model.put("message","Hello Jonel");
return "greeting";
}
}
My pom.xml is configured as a war and the dependencies are the following
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
</dependencies>
Jonel

To use jsp as your view resolver, you need another embedded servlet container for Spring Boot Starter Web. Add the following to your dependencies in pom.xml
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>

Related

Spring boot application rest call gives 404 Error in tomcat for next request

New to spring boot. Deployed war to tomcat server. The url after deploying is - http://localhost:8080/project-0.0.1-SNAPSHOT/. Which displays the welcome jsp page and works fine. The start button should call the controller start the project. But url call goes to http://localhost:8080/startProject instead of http://localhost:8080/project-0.0.1-SNAPSHOT/startProject.
After manually entering /startProject after the snapshot version the project works fine. What am I missing to configure? Please help. Thank you.
My code is a below
Welcome.Jsp
<a type="button" class="start-btn" href="/startProject">Start New Project</a>
Pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.4.RELEASE
com.project
mancala
0.0.1-SNAPSHOT
war
mancala
Demo project for Spring Boot
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
ProjectController.java
#Controller
public class ProjectController {
#Autowired
private ProjectService projectService;
#GetMapping(value = "/")
public String login() {
return "project";
}
#GetMapping(value = "/startProject")
public String startNewGame(ModelMap model) {
ProjectModel projectModel = projectService.startNewProject();
model.addAttribute("projectModel", projectModel);
return "project";
}
}
Since, you have set the server.servlet.context-path property in application.properties file to project-0.0.1-SNAPSHOT, the application is accessible via url: http://localhost:8080/project-0.0.1-SNAPSHOT/.
So, all your jsp page url's must begin with the context path: /project-0.0.1-SNAPSHOT/**.
That means, the startProject page url in your Welcome.jsp file should look like this:
<a type="button" class="start-btn" href="/project-0.0.1-SNAPSHOT/startProject">Start New Project</a>
I have a sample project that could prove helpful to you here: https://github.com/nkumashi/springboot-webmvc-demo.

Spring Boot + WebFlux. How to display a simple index.jsp?

Am trying to use spring webflux in a spring boot application to try to display a simple jsp page. For the life of me, am not able to make it work. It's not able to find the "view". It works fine if I use Spring webmvc instead.
Here's the simple setup:
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Here's the controller:
#Controller
public class WebController
{
#RequestMapping(value = { "/", "/index" }, headers = "Accept=text/html", method = RequestMethod.GET, produces = "text/html")
public Mono<String> index() {
return Mono.just ("index");
}
}
application.properties:
(Though I doubt this may not work with webflux)
spring.mvc.view.prefix=/jsp/
spring.mvc.view.suffix=.jsp
Folder structure:
Here's the folder structure where index.jsp is (I know index.jsp is in lots of places only because I was trying to see where I need to put it to make it work):
Finally here's the error I get when I try to load: https://localhost:8443/
(Partial stack)
java.lang.IllegalStateException: Could not resolve view with name 'index'. java.lang.IllegalStateException: Could not resolve view with name 'index'.
at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$3(ViewResolutionResultHandler.java:278)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ Handler com.xxxxxxx.xxxxxxx.controller.WebController#index() [DispatcherHandler]
Stack trace:
at org.springframework.web.reactive.result.view.ViewResolutionResultHandler.lambda$resolveViews$3(ViewResolutionResultHandler.java:278)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:107)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1755)
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:121)
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:359)
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onComplete(FluxConcatMap.java:268)
at reactor.core.publisher.Operators.complete(Operators.java:135)
What do I need to do to show a simple jsp page? Embedded server is Tomcat and deployed as jar file in spring boot.
Note: Displaying static files work. So this url works just fine: https://localhost:8443/js/test.js

Spring boot mongodb autoconfigure throws exception "Cannot determine embedded database driver class for database type NONE"

I am using Spring boot to develop a Spring batch application. I will need my application to write the data finally to MongoDB and thus needs to configure org.springframework.data.mongodb.core.MongoTemplate for org.springframework.batch.item.data.MongoItemWriter.
My pom.xml dependency section looks like this-
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<version>${spring.batch.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jongo/jongo -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jvnet.jaxb2_commons/jaxb2-basics-runtime -->
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-runtime</artifactId>
<version>1.11.1</version>
</dependency>
<!--<dependency>-->
<!--<groupId>de.flapdoodle.embed</groupId>-->
<!--<artifactId>de.flapdoodle.embed.mongo</artifactId>-->
<!--<version>1.50.5</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>cz.jirutka.spring</groupId>-->
<!--<artifactId>embedmongo-spring</artifactId>-->
<!--<version>RELEASE</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.6.0</version>
</dependency>
</dependencies>
The application.properties file looks like this
spring.data.mongodb.host=mongohost
spring.data.mongodb.port=27017
spring.data.mongodb.authentication-database=authdb
spring.data.mongodb.username=user
spring.data.mongodb.password=pwd
spring.datasource.driver-class-name=<< I don't know what to put here >>
Main class is also simple enough and looks like this-
#SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Now, whenever I try to run my Main class it gives out error
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
After researching a lot about this problem, I figured out that I need to let Spring know about my data store by providing the value of spring.datasource.driver-class-name in application.properties
spring.datasource.driver-class-name=com.mongodb.Server
If I provide com.mongodb.Server as my drive class name its not found on classpath and isn't recognised despite I have mongo java driver dependency on my classpath.
What should I put the value for mongoDB's driver-class-name provided I want to use mongo-java-driver?
If driver class name is not the cause of this issue, what should be the resolution of issue "Cannot determine embedded database driver class for database type NONE"mentioned in title of this question?
Try exluding DataSourceAutoConfiguration.class in your main class:
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Also you don't need this:
spring.datasource.driver-class-name
unless you need jpa configuration as well.

Spring Boot dont recognice Spring MVC

I am starting with SpringBoot, looks great, but I have some questions that I can't understand or find explained in the docs.
I created a new project with the Web, JPA, Security and MySQL dependencies. When my project is created, I go to create a #Controller class. Spring don't find #RequestMapping or ModelAndView classes.
I guessed that use the Web module of SpringBoot will add all the necessary dependencies to use SpringMVC (I read some examples and none add extra dependencies) and all work great with MVC.
These are my dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-groovy-templates</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Utils -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
</dependencies>
Other example, is the WebMvcConfigurerAdapter (from spring-mcv) class that I can't resolve:
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
This class is from, but I don't see Springboot include this dependy:
org.springframework
spring-webmvc
Maybe I am wrong and read some post that center all the info in Spring Boot, but don't show manual config in the poms.
WebApplication class (Auto Generated):
#SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class, args);
}
}
ServletInitializer.java class (Auto generated)
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebApplication.class);
}
}
Looks like my maven local repository is corrupted.
I was using these libraries in other projects and all works fine. Sorry for the time wasted. Anyway, I let the response for some users with similar problems.

Maven Module with Spring Boot

I am trying to configure Maven to use Spring Boot with multi modules, this is my structure:
- Parent
------ WebClient
------------ scr/main/java/config ---> Config Files
------------ scr/main/java/resources/WEB-INF ---> Template Files
------ Core
------ Services
------ Server
I have a config file where I put my ViewResolver:
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver setupViewResolver() {
// View Resolver
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
Here is my parent pom.xml modules and dependencies:
<modules>
<module>core</module>
<module>services</module>
<module>server</module>
<module>webclient</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- =========================== Spring ======================= -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<!-- Spring Security and MVC dependences -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.0.RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.0.RC1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.0</version>
</dependency>
</dependencies>
</dependencyManagement>
At my Server's POM file I have this dependencies:
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>core</artifactId>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>services</artifactId>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>webclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
My SpringBootApplication looks like this:
#SpringBootApplication
#ComponentScan({"config"})
public class ServerRunner {
public static void main(String [] args) {
SpringApplication.run(ServerRunner.class, args);
}
}
When I start my application, I see my mapping working and it seems that everything works well but the problem is that Spring does not find my templates:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/index.jsp
What is wrong with my config? Where should I put my template files?
Thanks for your help!
EDITED:
If I put my template files at Server Project (server\src\main\webapp) it works! So... How do I make the server to read webclient project templates? I need the templates in that submodule.
EDITED 2:
Solved avoid "jsp" files, see answer and comments
I think this is related to JSP limitations described in Boot reference documentation - you can't just read JSPs from anywhere in the classpath (whereas this works with other templating engines).

Resources