Reputation: 45
stackoverflow!
I've been battling this annoying bug for a couple of days. I've found many in the same situation, but their resolutions haven't worked for me. I am using Spring Boot and I am attempting to make a home page for my project. Currently, inside of my controller class I have this setup:
@RequestMapping("/")
public String getHomePage(Map<String, Object> model) {
return "home";
}
The issue I'm having is when I attempt to load the '/' url, I get this error message:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Mar 25 14:46:01 MDT 2020
There was an unexpected error (type=Internal Server Error, status=500).
Could not resolve view with name 'home' in servlet with name 'dispatcherServlet'
javax.servlet.ServletException: Could not resolve view with name 'home' in servlet with name 'dispatcherServlet'
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1353)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1118)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1057)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at
From this log, it appears that my controller can not find the home.jsp home page. I believe I originally had my .jsp page inside of the resources/view/ folder.
I've investigated the problems through others' experiences:
RequestMapping DisplatcherServlet no mapping found This post indicates their REST API isn't correctly working, but all components of my API are working as expected.
By default, where does Spring Boot expect views to be stored? His findings were interesting:
JSPs simply do not play well with Spring Boot as it has limitations depending on the embedded container chosen ... [He further explains all that is necessary is ] the default Spring Boot template and 2 ThymeLeaf dependencies with the views named as ViewName.html placed in src/main/resources/templates [is all that is needed].
However, even after attempting to modify my project by adding the depenencies thymeleaf and thymeleaf-spring4, removing my spring.mvc.view.prefix and spring.mvc.view.suffix (to set it to the default), and copying my home.html file to the src/main/resources/templates folder, the problem continued.
I actually had some more sources listed here originally, but my draft was lost and I can't be bothered to scour through all of those posts again. I need to get this question posted. The other sources had variations of where I should place my home.html/home.jsp. And with every suggestion, I make sure to switch between .jsp and .html to test them both out. Some said META-INF wasn't working correctly and to make sure you didn't have it as a folder name. Some said you need to nest a resource folder inside the currently existing resource folder in order for it to function. I followed these fixes as well, but none have successfully worked. There was no change in the error as well, it was still unable to find the home.jsp/home.html. I have updated my application.properties many times in order to test these solutions, currently my view prefix and suffix is this:
spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html
I did make sure to be up to date with my spring version (2.2.5.RELEASE). Another small note, I am using Spring Data REST, but my rest API is set to /api/
You may see my repository here: https://github.com/CloakingOcean/CampaignChronicle
I will also be listing here the main files and my dependencies.
(Other test folders removed for clarity of intended home.html location)
package com.exitium.campaignchronicle;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@SpringBootApplication
@EnableWebMvc
public class CampaignchronicleApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CampaignchronicleApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(CampaignchronicleApplication.class, args);
}
}
package com.exitium.campaignchronicle.controller;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Controller
public class MainController {
@RequestMapping("/")
public String getHomePage(Map<String, Object> model) {
return "home";
}
}
#
# JDBC properties
#
spring.datasource.url=jdbc:mysql://localhost:3306/campaignchronicle
spring.datasource.username=cloakingocean
spring.datasource.password=9QfsJGA4V6M74LB
#
# Spring Data REST properties
#
spring.data.rest.base-path=/api
spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html
# ==============================================================
# = Logging springframework
# ==============================================================
logging.level.org.springframework.jdbc=DEBUG
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.http=DEBUG
package com.exitium.campaignchronicle.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.anyRequest().authenticated()
.and().formLogin().permitAll();
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
<?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.2.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.exitium</groupId>
<artifactId>campaignchronicle</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>campaignchronicle</name>
<description>Note taking application for Dungeons & Dragons players</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Add dependency for Spring Data REST -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</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>
<!-- <dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Upvotes: 0
Views: 2812
Reputation: 276
I think we can use the Thymeleaf
.
Remove following from application.properties
spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html
To use thymeleaf template engine instead of JSP & JSLT, add dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
By default thymeleaf will look in src/main/resources/templates
with .html
files (jar deploy)
To deploy as war change default configuration in application.properties
Reference : https://github.com/hovermind/springboot-mvc/blob/master/README.md#thymeleaf-instead-of-jsp
Reference : By default, where does Spring Boot expect views to be stored?
Upvotes: 1