java - SpringBoot Controller 无法解析名称为 'home' 的 View

标签 java spring spring-boot spring-mvc jsp

计算器!

问题

我已经与这个恼人的错误作斗争了几天了。我发现很多人处于同样的情况,但他们的解决方案对我不起作用。我正在使用 Spring Boot,并尝试为我的项目制作主页。目前,在我的 Controller 类中我有这样的设置:

@RequestMapping("/")
public String getHomePage(Map<String, Object> model) {
    return "home";
}

我遇到的问题是当我尝试加载“/”网址时,我收到此错误消息:

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 

从该日志看来,我的 Controller 找不到 home.jsp 主页。我相信我最初的 .jsp 页面位于 resources/view/文件夹中。

我通过别人的经验调查了这些问题:

  • RequestMapping DisplatcherServlet no mapping found 这篇文章表明他们的 REST API 无法正常工作,但我的 API 的所有组件都按预期工作。

  • By default, where does Spring Boot expect views to be stored? 他的发现很有趣:

    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].

    但是,即使在尝试通过添加依赖项 thymeleaf 和 thymeleaf-spring4、删除 spring.mvc.view.prefix 和 spring.mvc.view.suffix (将其设置为默认值)并复制来修改我的项目之后我的 home.html 文件复制到 src/main/resources/templates 文件夹,问题仍然存在。

丢失草稿

实际上,我最初在这里列出了更多来源,但我的草稿丢失了,我懒得再次浏览所有这些帖子。我需要发布这个问题。其他来源对我应该放置 home.html/home.jsp 的位置有不同的要求。对于每一个建议,我都会确保在 .jsp 和 .html 之间切换以测试它们。有人说 META-INF 无法正常工作,并确保您没有将其作为文件夹名称。有人说您需要在当前现有的资源文件夹中嵌套一个资源文件夹才能使其正常工作。我也遵循了这些修复,但没有一个成功起作用。错误也没有变化,仍然找不到 home.jsp/home.html。为了测试这些解决方案,我已经多次更新了我的 application.properties ,目前我的 View 前缀和后缀是这样的:

spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html

我确实确保我的 Spring 版本 (2.2.5.RELEASE) 是最新的。另一个小注意事项,我正在使用 Spring Data REST,但我的 REST API 设置为/api/

您可以在这里看到我的存储库:https://github.com/CloakingOcean/CampaignChronicle

我还将在这里列出主要文件和我的依赖项。

错误消息:

Error Message

文件结构:

(为了清楚地了解 home.html 的预期位置,删除了其他测试文件夹)

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

}

应用程序属性

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

最佳答案

我认为我们可以使用Thymeleaf

从 application.properties 中删除以下内容

spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html

要使用 thymeleaf 模板引擎代替 JSP 和 JSLT,请添加依赖项

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

默认情况下,thymeleaf 将在 src/main/resources/templates 中查找 .html 文件(jar 部署) 要部署为 war,请更改 application.properties

中的默认配置

引用:https://github.com/hovermind/springboot-mvc/blob/master/README.md#thymeleaf-instead-of-jsp

文件结构 enter image description here

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

关于java - SpringBoot Controller 无法解析名称为 'home' 的 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60858859/

相关文章:

java - java中的 "integer"相当于javascript中的什么?

java - 有没有办法打印建立jdbc连接的数据库服务器IP?

java - web.xml中的Java错误页面不适用于所有请求

spring - mvn clean install 会导致 Surefire 错误

java - Thymeleaf 说 Model 属性为 null

spring - 使用 spring data mongo 更新插入 Mongo 文档

java - 设置具有相同的删除,但都不会覆盖另一个错误

java - Hibernate自动更新不会为特定实体创建表

java - 在 Spring Security 中实现自定义身份验证

logging - Spring Boot 日志记录与 logback 的问题