Spring Boot Web应用程序未在tomcat 9上运行

Posted

技术标签:

【中文标题】Spring Boot Web应用程序未在tomcat 9上运行【英文标题】:Spring boot web app not running on tomcat 9 【发布时间】:2019-03-08 18:07:42 【问题描述】:

我的网络应用程序在 Eclipse Photon STS、java 8 和 Spring Boot 2.02 上运行良好,并使用端点嵌入了 tomcat:

http://localhost:8081/DataViewer/tspsPatentSearch

但是当我将代码编译成 DataViewer.war 文件(使用 mvn 包)并在 Linux 上的 Tomcat 9 上运行它时 带端点:

http://myserver.com:8081/DataViewer/tspsPatentSearch

我知道臭名昭著:

Whitelabel Error Page
There was an unexpected error (type=Not Found, status=404).
/DataViewer/tspsPatentSearch

我的 pom.xml 文件是:

`<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion>
<groupId>com.clarivate</groupId>
<artifactId>dataviewer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>dataviewer</name>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <start-class>com.clarivate.dataviewer.DvMain</start-class>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

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

    <!-- DS may need to remove for tomcat installation -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-slf4j-impl</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

   <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.1.0</version>
    </dependency>


    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

   <!-- Required to find ojdbc6, because Oracle don't make it available to maven-->
    <repositories>
        <repository>
          <id>codelds</id>
          <url>https://code.lds.org/nexus/content/groups/main-repo</url>
        </repository>
      </repositories>

<build>
    <finalName>DataViewer</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId> 
            <configuration>
                <mainClass>com.clarivate.dataviewer.DvMain</mainClass>
            </configuration>    
        </plugin>
    </plugins>
</build>


<description>TSPS data viewer</description>

在 application.properties 我有:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
server.servlet.path=/DataViewer 

我的主要课程是:

package com.clarivate.dataviewer;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
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;

@SpringBootApplication

public class DvMain extends SpringBootServletInitializer 

    static Logger logger = LogManager.getRootLogger();

    public static void main(String[] args) 
        logger.debug("DS1A in main()");
        SpringApplication.run(DvMain.class, args);
        logger.info("DS1C finished.");
    


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

我的 MainController.java 有:

@GetMapping("/tspsPatentSearch")
public String tspsPatentSearch(Model model) 
     model.addAttribute("tspsPatent", new TspsPatent());

     return "tspsPatentSearch";                 

war 文件解压正常,没有错误。在 catalina.out 我们有:

2018-10-04 12:09:09.954  INFO 12950 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/tspsPatentSearch],methods=[POST]" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(com.clarivate.dataviewer.model.TspsPatent,org.springframework.ui.Model,org.springframework.validation.BindingResult)

并且没有错误。我试过this 即我的包结构是正确的,this 即我的 jsp 位于正确的位置 (data_viewer\src\main\webapp\WEB-INF\jsp) 我现在没有想法了。非常感谢任何帮助

编辑:如果我将 tspsPatentSearch.jsp 复制到 war 文件的***目录中,则 tomcat 会找到它。所以看起来tomcat忽略了:

spring.mvc.view.prefix=/WEB-INF/jsp/

或根本找不到 application.properties。

【问题讨论】:

你试过myserver.com:8081/dataviewer/tspsPatentSearch吗? 试试http://localhost:8081/tspsPatentSearch 谢谢,我刚刚尝试了这两个端点,我得到了同样的 404 错误 您能否发布完整的 DvMain 类,包括所有导入 @kj007 我已经更新了我原来的帖子 【参考方案1】:

将此添加到您的application.properties

server.servlet.contextPath=/

我已经获取了您的示例代码,假设您将 MainController 简单地注释为 @Controller,将部署放在一起。我改变了一些事情,但我相信这是做到这一点的一点。我还没有找到任何参考资料来解释为什么 Tomcat 可能需要它,但我打算继续寻找。如果我发现任何东西,我会通知你。

编辑:

我注意到 Spring 2.0.2 中与此问题相关的一些重复日志记录:https://github.com/spring-projects/spring-boot/issues/13470

这个问题在 2.0.4 中出现了,所以我升级了。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

此外,我删除了server.servlet.contextPath=/ 条目,tada 我仍然可以访问我设置的 Hello World jsp。如果您可以升级,也许您可​​以在向application.properties 添加一些东西之前尝试一下,这可能被认为是重复的功能。至少我可以向您保证更好的日志记录体验。

编辑#2:

到目前为止,没有确凿证据,但这些(从 2.0.4 开始)可能是相关的:

Provide a consistent way to discover the primary DispatcherServlet's path

Dispatcher servlets with a custom servlet name are not found by the mappings endpoint

在 2.0.3 的表面扫描中似乎没有任何东西。我现在要休息一下,给你一个尝试一些东西的机会。祝你好运!

编辑#3:

很抱歉继续建议您切换环境,但我注意到我测试的内容与您正在使用的内容之间的一个区别是,您似乎在使用 Tomcat-9.0.0.M20使用9.0.12 进行测试。

无论您是否想升级,有几点需要注意和/或做:

1) 如果问题与以前不同,请使用您现在所拥有的内容更新您的问题。将server.servlet.contextPath=/ 包含在您的application.properties 中,以便其他人看到您所做的事情。

2) 您在 spring-boot-starter-web 下对 spring-boot-starter-tomcat 的排除似乎没有任何作用 - 您可以通过比较删除前后运行 mvn dependency:tree 的输出来验证。

3) 我也不确定是否需要您的 spring-web 依赖项,因为它默认是在 spring-boot-starter 下引入的。

4) 现在到你的输出。 Spring Boot 即将推出(注意横幅),您的类正在被发现并采取行动。

catalina.out.DEBUG 也在您的 DS.log 中,开始时间 ~ 08:35:38.162

2018-10-12 09:30:17.322 DEBUG 55745 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/controller/MainController.class]
2018-10-12 09:30:17.328 DEBUG 55745 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/database/ReadFromDb.class]
2018-10-12 09:30:17.356 DEBUG 55745 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/service/FileFuncs.class]
2018-10-12 09:30:17.357 DEBUG 55745 --- [           main] o.s.c.a.ClassPathBeanDefinitionScanner   : Identified candidate component class: file [/data/apps/tomcat/apache-tomcat-9.0.0.M20/webapps/DataViewer/WEB-INF/classes/com/clarivate/dataviewer/service/StringFuncs.class]
...
2018-10-12 09:30:19.417  INFO 55745 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/tspsPatentSearch],methods=[POST]" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(com.clarivate.dataviewer.model.TspsPatent,org.springframework.ui.Model,org.springframework.validation.BindingResult)
2018-10-12 09:30:19.417  INFO 55745 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "[/tspsPatentSearch],methods=[GET]" onto public java.lang.String com.clarivate.dataviewer.controller.MainController.tspsPatentSearch(org.springframework.ui.Model)
...
2018-10-12 09:30:19.769  INFO 55745 --- [           main] com.clarivate.dataviewer.DvMain          : Started DvMain in 3.125 seconds (JVM running for 5.845)

我确实注意到了在 09:32:11 为您的请求返回的到 /error 的映射。

我觉得这很奇怪:

2018-10-12 09:32:11.758 DEBUG 55745 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/DataViewer/DataViewer/error]

在 DS.log 中有所不同:

2018-10-12 08:36:56.136 DEBUG 6992 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/DataViewer /error]

特别是/DataViewer/DataViewer/error - 你尝试过请求http://localhost:8081/DataViewer/DataViewer/tspsPatentSearch

一般来说,这看起来好像一切都即将到来,但某处存在错误配置,不允许请求映射到处理程序。

【讨论】:

感谢您的建议,我正在研究它。我遇到的问题是,当我将 spring-boot-starter-parent 版本更改为 2.0.4 时,我的 war 文件中有 2 组 spring 文件,2.0.2 和 2.0.4(但我的构建中只有 2.0.4图书馆)。我已经尝试过 Maven -> Update Project 和其他各种东西,但到目前为止还没有运气。希望我能解决它并回复你。 我修复了双弹簧文件,但现在localhost:8081/DataViewer/tspsPatentSearch(在 Eclipse 上)与 spring-boot-starter-parent 2.0.2 配合良好,使用 spring-boot-starter-parent 2.0 返回 404 .4.当我切换回 2.0.2 时,它再次起作用(仅在 eclipse 上) @DS。昨晚我没有在 Eclipse 中进行任何测试,所以我没有给你任何东西。我没有找到一种令人满意的方法来内省该过程以查看映射到哪里。如果它有帮助并且如果您还没有这样做,您可以将 logging.level.root=DEBUG 添加到 application.properties 并获得大量输出,其中可能包含有关 JSP 编译(或不存在)的信息。我对这种语法并不肯定——我没有昨晚的测试台。 我已打开调试。生成的 eclipse 日志文件在这里:drive.google.com/file/d/12KjPkSZkIsmXvubyV1AB2koX5tLfw9hU/…。 “DS1C”之前的位是弹簧启动时,DS1C 之后的位是您尝试到达端点localhost:8081/DataViewer/tspsPatentSearch 时。该文件有 150K 行长! myserver.com:8081/DataViewer/DataViewer/tspsPatentSearch 工作 :),不知道为什么。非常感谢。【参考方案2】:

确认。 Tomcat将war文件名添加到端点,所以如果我们创建DataViewerX.war并设置:

server.servlet.path=/DataViewer

那么在外部tomcat上运行的终点是:

myServer.com/DataViewerX/DataViewer/tspsPatentSearch 

但是当我们在 Eclispe 上运行时,使用源代码,那么终点是:

http://localhost:8081/DataViewer/tspsPatentSearch

这有点烦人,但不是主要问题。一种解决方法是调用war文件ROOT.war,然后tomcat忽略war文件名并且2个端点相同,但是我在webapps目录中有多个war文件,所以这个解决方案对我来说是不可接受的。 如果有人知道让两个端点相同的方法,请说出来,但这并不重要。

【讨论】:

以上是关于Spring Boot Web应用程序未在tomcat 9上运行的主要内容,如果未能解决你的问题,请参考以下文章

Spring-boot简单的理解

Spring/Boot - JWT 未在 GET 请求中获取

CSS未在spring boot应用程序中加载

bootstrap.yml 未在 Spring Boot 2 中加载

从 Spring Boot 应用程序启动的 Cucumber 未在 jar 中找到胶水类

spring boot 应用程序未在 Tomcat 中配置的端口号上启动