why isn't Spring MVC finding the path to my views? - java

I'm new to Spring and I'm trying to make a simple web app, however I cannot get started with the basics and cant make even a HelloWorld application.
Here is what I am Using:
Spring 5
Spring boot 2.1
Eclipse Photon, I used the add-on Spring Tools Version 3.9.6 to create the proyect
Here is what I did:
Created via File -> New -> Spring Starter Proyect, selected type package type as WAR, also in the dependencies section I selected Web
Added jstl and jasper dependencies to the pom.xml, here is the whole file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.logback.app</groupId>
<artifactId>spring-boot-logback</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-boot-logback</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
**<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>**
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
My view template is as follows:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1" />
<title>Logback</title>
</head>
<body>
<h1>Hello world</h1>
<h2><c:out value="${titulo}"/></h2>
</body>
</html>
This is my controller:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class IndexController {
#GetMapping("/index")
public String index(Model model) {
model.addAttribute("titulo", "Pruebas Logback");
return "index";
}
}
And I added these to the application.properties file
spring.mvc.view.prefix: /WEB-INF-/views/
spring.mvc.view.suffix: jsp
With all these configuration it should work, but when I enter the address localhost:8080/index it throws what it looks like a 404 error
And the strangest thing is that neither in the web browser console or in the Eclipse console are errors that point out to the right direction.
What do you think it can be?
Thanks ind advance

Thanks to Piotr Podraza I realized my mistake
Changed
spring.mvc.view.prefix: /WEB-INF-/views/
spring.mvc.view.suffix: jsp
to
spring.mvc.view.prefix: /WEB-INF/views/
spring.mvc.view.suffix: .jsp
The path to my views was incorrect, and I was missing the period of the jsp suffix
Thank you!

Related

Problems accessing REST endpoints from Springboot application deployed on Tomcat

I am developing a springboot REST application with Eclipse, but I have a problem deploying it to Tomcat 10.0.22. When I run my application from the IDE the endpoints are working fine, they returns me the correct JSONs but when I try to access them from my server they throw a 404 error.
I am packaging it as war. I have created the project from https://start.spring.io/ setting Spring web dependency, java 18 and packaging war. I imported it to eclipse as an existing maven project.
To be sure that I deployed it correctly I had created a jsp file and load it as index.jsp and it is showing correctly on the deployed server and the IDE.
I have tried to restart the proyect, change the java version in both, export the proyect as jar, to deploy it on another tomcat version, to extend SpringBootServletInitializer from the main class and override the confirm method, without the method implemented and without extending it from anywhere.
I don't understand why when I deploy it to the Tomcat server from the Tomcat manager the endpoint calls are throwing a 404 error. I think that is possible that Tomcat is not loading Springboot libraries, because I do not see the console Spring initializing message when I start the server from console, but I do not know how to solve this or if it is what is happening. Can anyone help me please.
This is my main class, TestApplication.java:
package com.testing.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
This is my servlet initializer application, ServletInitializer.java:
package com.testing.test;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication.class);
}
}
This is my controller, UserController.java:
package com.testing.test.controllers;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class UserController {
#PostMapping("/test/User")
public String user(#RequestParam(name="id", defaultValue = "NO_ID_RECEIVED") String id) {
return String.format("The user ID is: %s",id);
}
}
This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.testing</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>18</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.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The mentioned index.jsp:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>Let's see if it deploys</h2>
</body>
</html>
EDIT: Because I have had a questions about the structure below this I am appending a picture of it.
Project folder structure
Just to be sure have you put your JSP files under web-content and not under WEB-INF because in Eclipse the files are not accessed there by the server.
And one more thing try to check server location and see whether Tomcat is installed in the correct server location and it is showing in your Eclipse,if not try changing your server location to the location where Tomcat is installed and restart your server.

Application.properties not being found

Application.properties doesn't get pick up.
Very small program not sure what's wrong, I've google and did research.
But when I use this code in FirstController.java it does work....
return new ModelAndView("/WEB-INF/jsp/welcome.jsp","dateAndTime",dateAndTime);
FirstController.java
package com.vpp.fleetman.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
#Controller
public class FirstController {
#RequestMapping("/home.html")
public ModelAndView firstPage(){
Date dateAndTime = new Date();
//This work, I just want to remove the hard coded and use application.properties
// return new ModelAndView("/WEB-INF/jsp/welcome.jsp","dateAndTime",dateAndTime);
//Let's use a view resolver for the views
return new ModelAndView("welcome","dateAndTime",dateAndTime);
}
}
webapp/WEB-INF/jsp/welcome.jsp
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<h1>Welcome from Intelij ..... Time is: ${dateAndTime} </h1>
<c:forEach var="i" begin="1" end="5">
<p>${i}</p>
</c:forEach>
application.properties the default one that is set with the facet
sping.mvc.view.prefix:/WEB-INF/jsp/
spring.mvc.view.suffix:.jsp
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.virtualpairprogrammers</groupId>
<artifactId>fleetman</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fleetman</name>
<description>VPP Fleet Management Application</description>
<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.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I get this error when I http://localhost:8080/home.html
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Apr 27 13:57:24 EDT 2021
There was an unexpected error (type=Not Found, status=404).
/welcome.jsp
As soon I use the reference to application.properties it doesn't work... vs when I keep the hard coded ref ?? any guidance would be appreciated.
Thanks for your suggestion.
The answer is what Luke Woodward propose... in the file application.properties.
Typo Error.
Sping.mvc.prefix:/WEB-INF/jsp/ vs spring.mvc.view.prefix:/WEB-INF/jsp/
I've also tried with : and = and both work.
Thanks for your support appreciated.

Error displaying HTML with a simple thymeleaf Spring boot application

I am trying to display a HTML file with Spring and Thymeleaf but when I hit the controller from the browser, I get error shown as below:
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [error], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189) ~[thymeleaf-spring5-3.0.11.RELEASE.jar:3.0.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1373) ~[spring-webmvc-5.2.9.RELEASE.jar:5.2.9.RELEASE]
below is my Controller code..
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.thymeLeafAppDemoController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class DemoController {
#GetMapping(value="/show")
public String stamp(){
return "helloworld";
}
}
this is my application.properties file:
server.error.whitelabel.enabled=false
this is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dafe</groupId>
<artifactId>thymeLeafAppDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>thymeLeafAppDemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
below is the Main Spring boot class:
package com.thymeLeafAppDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ThymeLeafAppDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ThymeLeafAppDemoApplication.class, args);
}
}
the file I am trying to display is a helloworld.html file and this is the path src/main/resources/templates/helloworld.html. The url I used on the browser is http://localhost:8080/show.
This is the content of the file:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Demo</title>
</head>
<body>
<p th:text="'Time on the server is ' "/>
</body>
</html>
Please help me fix this issue... it is my first time with thymeleaf. Thanks.
I finally figured the answer out so I thought to share for the benefit of others in the future. The reason I was having the issue is because Spring Boot could not find my controller class. By default, Spring Boot will component scan the current package of main spring app and all sub-packages.
The package of my main spring app is: com.myThymeLeafDemo
However, my controller is not in a proper sub-package. The controller is current in package: com.myThymeLeafDemoController. However, it should be in a sub-package of com.myThymeLeafDemo
I resolved this by refactoring the package name:
old name: com.myThymeLeafDemoController
new name: com.myThymeLeafDemo.Controller
make note of the "." ... this makes it a subpackage of the main package. Now Spring Boot is be able to find my controller. Once I run my app then it works as desired.

Jar file not working in target folder but working in project folder

When I run the project in STS, it's working fine. All the pages in the webapp folder are loading in the browser. But when I build the project and run the JAR file (folder: D:\SpringBoot Projects\DemoExample\target) and go to the page URL, I'm getting Whitelabel error.
In another project I used spring security- In that project the login page is loading fine, but all the JSP pages in the webapp folder are not loading just like the above example.
While trying to solve this problem, I moved the JAR file from target folder to project folder (D:\SpringBoot Projects\DemoExample) and again ran the JAR file, now the JSP pages are loading fine. The JSP pages are only loading in that folder, if I moved the file to another folder, the pages are not loading.
I want to make sure that I can run the JAR file from any folder.
POM File:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.project</groupId>
<artifactId>DemoExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>DemoExample</name>
<description>Project</description>
<properties>
<java.version>11</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-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jasper -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>9.0.37</version>
</dependency>
</dependencies>
<build>
<outputDirectory>${basedir}/${target.dir}/classes</outputDirectory>
<testOutputDirectory>${basedir}/${target.dir}/test-classes</testOutputDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Main Class:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoExampleApplication {
public static void main(String[] args) {
SpringApplication.run(DemoExampleApplication.class, args);
}
}
Controller:
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
#org.springframework.stereotype.Controller
public class Controller {
#RequestMapping("/")
public String home() {
return "home.jsp";
}
}
JSP File:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Hello
</body>
</html>
Project Structure
Running Jar file in target folder
Result after running Jar file in target folder
Running Jar in project folder
Result after running Jar file in project folder

JDBC driver not found for PostgreSQL database while building with Maven

I am following a course "Learning Path: Enterprise Web Programming with Java" by O'Reilly. I have re-written code for a simple webapp using PostgreSQL. I build it with Maven and run it on a Tomcat server. The database is up and filled. I receive the following error:
javax.servlet.jsp.JspException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver found for ${ourDS}"
I have found that it is usually a result of no postgres dependency. I have also tried adding other dependencies like tomcat plugin, etc.
I understand that I miss a small piece of dependency or some file somewhere, but I can not find out what is it.
The main .jsp file has a following code:
<%# page errorPage = "error.jsp" %>
<%# taglib uri = "http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri = "http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!DOCTYPE html>
<html>
<head>
<title>List of products in our database</title>
<link rel = "stylesheet" href = "style.css" type = "text/css"></link>
</head>
<body>
<sql:setDataSource
var = "ourDS"
driver = "org.postgresql.Driver"
url = "jdbc:postgresql://localhost:5432/skistuff"
user = "******"
password = "*******"
/>
<sql:query var = "productList" dataSource = "${ourDS}">
SELECT * FROM skisEtc ORDER BY id;
</sql:query>
<!-- Some kind of display -->
</body>
In contrary to the lecturer, I use Maven instead of Ant, so I have to figure it out other way. From what was mentioned in the course, I prepared the following pom file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.training.skis</groupId>
<artifactId>skispagebasic</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>skispagebasic Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.1.4.jre7</version>
</dependency>
</dependencies>
<build>
<finalName>skispagebasic</finalName>
</build>
</project>

Categories