Shawn Peery
Shawn Peery

Reputation: 45

SpringBoot Controller could not resolve view with name 'home'

stackoverflow!

Problem

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:

Lost Draft

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.

Error Message:

Error Message

File Structure:

(Other test folders removed for clarity of intended home.html location)

File Structure (Link)

CampaignchronicleApplication.java

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);
    }

}

MainController.java

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";
    }

}

application.properties

#
# 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

SecurityConfig.java

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();
    }
}

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.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 &amp; 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

Answers (2)

Ajay Singh Pundir
Ajay Singh Pundir

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

File structure enter image description here

Reference : By default, where does Spring Boot expect views to be stored?

Upvotes: 1

NewCoder2015
NewCoder2015

Reputation: 47

Change @RequestMapping("\") to @RequestMapping("")

Upvotes: 0

Related Questions