IntelliJ 中的 Gradle Spring Boot 应用程序无法识别 WEB-INF 文件夹中的 Web 资源

Posted

技术标签:

【中文标题】IntelliJ 中的 Gradle Spring Boot 应用程序无法识别 WEB-INF 文件夹中的 Web 资源【英文标题】:Gradle Spring Boot Application in IntelliJ is not recognizing web resources in WEB-INF folder 【发布时间】:2021-09-11 07:05:13 【问题描述】:

这是一个源自我之前的问题的新问题。我正在编写一个使用 .jsp 作为 mvc 视图的 Spring Boot 应用程序。我的文件夹结构是:

我的application.properties如下:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.mvc.view.prefix= /WEB-INF/view/
spring.mvc.view.suffix= .jsp

最后我的HomeController.java如下:

@Controller
@Slf4j
public class HomeController 

    @RequestMapping(value="/", method= RequestMethod.GET)
    public String showPage()
    
        return "main-menu";
    

该程序应该在我的主页 localhost:8080 上呈现 main-menu.jsp 文件,但我得到了一个错误。这是错误的堆栈跟踪:

2021-06-28 20:40:12.243 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : GET "/", parameters=
2021-06-28 20:40:12.245 DEBUG 27388 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.springdemo.mvc.HomeController#showPage()
2021-06-28 20:40:12.257 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2021-06-28 20:40:12.257 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView  : View name 'main-menu', model 
2021-06-28 20:40:12.258 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView  : Forwarding to [/WEB-INF/view/main-menu.jsp]
2021-06-28 20:40:12.261 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : "FORWARD" dispatch for GET "/WEB-INF/view/main-menu.jsp", parameters=
2021-06-28 20:40:12.263 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
2021-06-28 20:40:12.263  WARN 27388 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler     : Path with "WEB-INF" or "META-INF": [WEB-INF/view/main-menu.jsp]
2021-06-28 20:40:12.263 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler     : Resource not found
2021-06-28 20:40:12.263 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Exiting from "FORWARD" dispatch, status 404
2021-06-28 20:40:12.264 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 404 NOT_FOUND
2021-06-28 20:40:12.265 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters=
2021-06-28 20:40:12.266 DEBUG 27388 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2021-06-28 20:40:12.278 DEBUG 27388 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2021-06-28 20:40:12.281 DEBUG 27388 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 404

据我所知,这似乎是 IntelliJ 设置方式或 Gradle 设置方式的问题。无论哪种方式,资源目录或文件都无法识别。

以下是我做过/尝试过的一些事情:

    在项目结构中,我将文件夹 WEB-INF 添加为模块中的 Web 资源目录。 在设置 >>> 编译器中,我将 !?.jsp 添加到资源模式中 最后,在 gradle.build 中,我添加了 sourceSets(这导致了错误,我将其删除)。

感谢您为我提供的任何帮助。

编辑:

我已将我的项目结构更新如下。

我还在我的 gradle.build 中添加了 apply plugin: 'war',并将该文件夹添加到我的项目方面。

我仍然遇到资源未找到的相同问题。

【问题讨论】:

你的结构是错误的。 WEB-INF 应该在 src/main/webapp 而不是 src/main/resources。此外,jsp 仅适用于 jar 文件,并且在使用嵌入式服务器时有限制。 我已经调整了结构,但仍然出现错误(请参阅我在主帖中的编辑)。至于 jsp 文件,我只使用它,因为它是使用我的 Udemy 课程讲师的建议页面。是否有我可以/应该使用的替代文件类型? 如前所述,这只适用于 war 文件(即打包一个 Web 应用程序,它不适用于常规 jar)。所以你也需要改变它。另外,您为什么要手动弄乱折叠?您正在使用 Gradle,因此将其导入 IDE 就足够了。 这很可能源于我对 IntelliJ 的缺乏经验。我在 IntelliJ 中创建了一个新的 spring 项目。这使用了来自 start.spring.io 的 Spring Initializer。我用 Jar 打包在 Java 8 中构建。当我这样构建时,没有 webapp 文件夹,所以我手动添加了它。我可以尝试直接在 spring.io 上构建,但我认为不会有什么不同。我对 Gradle、Spring 和 IntelliJ 非常陌生。 【参考方案1】:

在同事的帮助下,我得以解决。我必须对我的 SpringMvcDemoApplication.java 文件和我的 gradle.build 进行一些更改。以下是更改。

SpringMvcDemoApplication(为 InternalResourceViewResolver 添加 bean):

@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
public class SpringMvcDemoApplication extends SpringBootServletInitializer 

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) 
        return builder.sources(SpringMvcDemoApplication.class);
    

    @Bean
    public ViewResolver internalResourceViewResolver() 
        InternalResourceViewResolver bean = new InternalResourceViewResolver();
        bean.setViewClass(JstlView.class);
        bean.setPrefix("/WEB-INF/view/");
        bean.setSuffix(".jsp");
        return bean;
    

    public static void main(String[] args) 
        SpringApplication.run(SpringMvcDemoApplication.class, args);
    


HomeController.java(删除@Slf4j)

@Controller
public class HomeController 

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showPage()
    
        return "main-menu";
    

gradle.build(添加tomcat和jstl依赖):

plugins 
    id 'org.springframework.boot' version '2.5.1'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'


group = 'com.example.springdemo'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories 
    mavenCentral()

apply plugin: 'war'

dependencies 
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.projectlombok:lombok:1.18.18'
    implementation group: 'javax.servlet', name: 'jstl', version: '1.2' //addee
    implementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'



test 
    useJUnitPlatform()

现在一切正常。

【讨论】:

【参考方案2】:

从上一个问题开始 https://***.com/a/68158449/14967681 请尝试通过将 WEB-INF 从资源中取出到新文件夹作为 webapp 来更改您的项目结构。我不确定为什么它无法检测到提到的配置的资源内的文件夹,但这应该适合你。 这是您应该使用的项目结构:https://i.stack.imgur.com/IZXx1.png

【讨论】:

你好阿斯敏。我对文件结构进行了建议的更改,但仍然出现错误。 请分享spring-mvc-demo-servlet.xml 中的内容或删除该文件后尝试。 我尝试删除spring-mvc-servlet.xml,但堆栈跟踪仍然没有变化。它仍然说找不到资源。 根据我的经验,这可能是因为 HomeController.java 中的 / 索引到 resources/static/index 。请尝试将路径更改为 /home 我尝试添加/home,没有任何变化。除了我现在必须尝试导航到 localhost:8080/home。我相信主要问题在于堆栈跟踪,它指出"FORWARD" dispatch for GET "/WEB-INF/view/main-menu.jsp", parameters=。它显然认识到它必须去的路径,但它没有去那里。我试图将文件更改为 .html,并将其添加到设置中的编译器中,但它仍然没有加载文件。由于文件夹结构、IDE 设置或 gradle.build,IntelliJ 无法识别该文件。

以上是关于IntelliJ 中的 Gradle Spring Boot 应用程序无法识别 WEB-INF 文件夹中的 Web 资源的主要内容,如果未能解决你的问题,请参考以下文章

intellij idea 怎么gradle创建spring boot

thymeleaf-spring4:jar 找不到工件 - gradle intellij

intellij idea 2017 gradle构建spring-boot web项目

使用 Intellij 在 Spring Boot 中使用 Gradle 构建 docker 映像

使用 Groovy、IntelliJ 和 Gradle 在项目中“重新运行 Spring Boot 配置注释处理器”

intellij idea gradle 瀵煎叆 spring 闂璁板綍