stackoverflow!
我已经与这个烦人的bug战斗了几天。我发现许多人处在相同的情况下,但是他们的解决方案对我没有用。我正在使用Spring Boot,并且试图为我的项目创建主页。当前,在我的控制器类中,我有以下设置:
@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
从此日志中,似乎我的控制器找不到home.jsp主页。我相信我最初将我的.jsp页面放在resources / view /文件夹中。
我已经通过他人的经验调查了这些问题:
RequestMapping DisplatcherServlet no mapping found这篇文章表明他们的REST API无法正常工作,但我的API的所有组件均按预期工作。
By default, where does Spring Boot expect views to be stored?他的发现很有趣:
JSP不能很好地与Spring Boot配合使用,因为它有局限性,取决于所选择的嵌入式容器 ... [他进一步解释了所有必要的事情]默认的Spring Boot模板和2个ThymeLeaf依赖项以及视图名为src / main / resources / templates中的ViewName.html [仅需使用]。
但是,即使尝试通过添加依赖关系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,目前,我的视图前缀和后缀是:
spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html
我确实确保了解最新版本(2.2.5.RELEASE)。另一个小注意事项,我正在使用Spring Data REST,但我的其余API设置为/ api /
您可能会在这里看到我的存储库:https://github.com/CloakingOcean/CampaignChronicle
我还将在这里列出主文件和我的依赖项。
((其他测试文件夹已删除,目的是为了清楚home.html的位置)
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>
将@RequestMapping("\")
更改为@RequestMapping("")
我认为我们可以使用Thymeleaf
。
从application.properties中删除以下内容
spring.mvc.view.prefix=/resources/view/
spring.mvc.view.suffix=.html
要使用百里香模板引擎而不是JSP和JSLT,请添加依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
默认情况下,百里香叶将在src/main/resources/templates
中带有.html
文件(jar部署)要在application.properties
参考:https://github.com/hovermind/springboot-mvc/blob/master/README.md#thymeleaf-instead-of-jsp
参考:By default, where does Spring Boot expect views to be stored?