Spring Boot REST Controller 部署在外部 tomcat 9 服务器上时返回 404

Posted

技术标签:

【中文标题】Spring Boot REST Controller 部署在外部 tomcat 9 服务器上时返回 404【英文标题】:Spring Boot REST Controller returns 404 when deployed on external tomcat 9 server 【发布时间】:2018-02-27 01:20:43 【问题描述】:

我有一个 Spring Boot Rest Web 应用程序,可以在嵌入式服务器上完美运行。但是,按照博客https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file 中提到的步骤进行操作后,当我向服务器上的资源发送请求时收到 404 错误消息。我在本地使用了 java 1.8.0_212 并使用了 java 1.8.0_131 并部署了我的应用程序在服务器上的tomcat 9上。令我困惑的一件事是可以访问扩展 CrudRepository 的存储库。下面是我的应用程序的入口点。

@SpringBootApplication
@ComponentScan(basePackages = "com.dbe.ref")
public class RefmsApplication extends SpringBootServletInitializer 

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

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

还有我的 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dbe.ref</groupId>
    <artifactId>refms</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>refms</name>
    <description>project for Rural electrification fund</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>LATEST</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.RefmsApplication</start-class>
    </properties>

    <dependencies>

        <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-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <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-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>2.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>angularjs</artifactId>
            <version>1.4.10</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.4</version>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>font-awesome</artifactId>
            <version>4.7.0</version>
        </dependency>
        <dependency>
            <groupId>eu.michael-simons</groupId>
            <artifactId>wro4j-spring-boot-starter</artifactId>
            <version>0.3.4</version>
        </dependency>
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.14</version>
        </dependency>

        <dependency>
            <groupId>net.sourceforge.dynamicreports</groupId>
            <artifactId>dynamicreports-core</artifactId>
            <version>5.0.0</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>refms</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

这是日志的一部分:

2017-09-19 10:38:20.564  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'errorPageFilter' to: [/*]
2017-09-19 10:38:20.565  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-19 10:38:20.566  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-19 10:38:20.568  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-19 10:38:20.568  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-19 10:38:20.571  INFO 6660 --- [           main] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2017-09-19 10:38:20.571  INFO 6660 --- [           main] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'configurableWroFilter' to urls: [/wro4j/*]
2017-09-19 10:38:20.572  INFO 6660 --- [           main] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServletRegistration' to [/refms/*]
2017-09-19 10:38:20.573  INFO 6660 --- [           main] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]

【问题讨论】:

你能发布tomcat和应用程序的日志吗(例如catalina.log和application.log)?最好看一下它是否启动正常并查看它部署在哪个上下文根上。 如果您将应用程序部署在任何 ApplicationServer 的屋顶下,则处理 HTTP 请求将不是弹簧的责任。您能否向我们提供更多有关您部署它的位置以及设置的信息? 在哪个 URL 上得到 404 ? 当我调用身份验证 api localhost:8080/refms/api/account/authenticate 那么您能否也发布您实现此端点控制器的源代码 - /refms/api/account/authenticate 【参考方案1】:

默认情况下在嵌入式服务器和外部服务器上部署应用程序有一点区别。

使用嵌入式服务器,您可以使用以下方式访问您的应用程序:

http://localhost:<port>/<resourceName>

如果您将war 部署在另一个容器中,则需要添加应用程序名称,其版本如下:

http://localhost:<port>/<applicationNameWithVersion>/<resourceName>

例如,如果您部署此 example,则嵌入式服务器的 URL 为:

http://localhost:8080/greeting

以及外部部署应用程序的 URL(如果喜欢):

http://localhost:8999/gs-rest-service-0.1.0/greeting

注意:这个 URL 是我的应用服务器的,所以它可能对你的有一些变化。

如果您需要帮助,请发表评论。

【讨论】:

在springboot中,您可以在application.properies中定义属性,例如server.contextPath=YourExample,以便在浏览器中访问localhost:8080/YourExample/greeting 你是对的@HirenPandit,这就是我“默认”豪宅的原因。【参考方案2】:

检查是否

<build>
     <finalName>refms</finalName>
         ...
</build>

在pom.xml中对应

server.contextPath=/refms

在application.properties中检查

<Context path="/refms"/>

在 context.xml 中。也许你在tomcat中的根上下文 部署后不同。

另外,改变这个依赖

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

通过这个

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

用于外部 tomcat

【讨论】:

【参考方案3】:

查看src/main/java中的根包,它应该与POM groupid中提到的包名相同,即。 com.dbe.ref 如果有任何不匹配,就会出现同样的问题。

【讨论】:

【参考方案4】:

确保您已将上下文路径添加到您的 Spring Boot 应用程序。通常它位于 src\main\resources 内的 application.properties 文件中。在该属性文件中,添加属性:

server.contextPath=/refms

您应该能够使用以下链接访问您的应用程序 localhost:8080/refms/api/account/authenticatelocalhost:8080/refms-xxxx/api/account/authenticate(其中 xxxx 是您的工件版本)

【讨论】:

【参考方案5】:

在您提到的 cmets 中,/authenticate 给出了 404,这是因为您已将登录过程 URL 设置为“authenticate”。这是登录表单发布到的 URL。如果未指定,则默认为 /login。 Spring Security 框架拦截该 URL 并获取登录名和密码参数。

【讨论】:

【参考方案6】:

当您将应用程序部署到 Tomcat 时,URL 取决于应用程序部署所在的上下文路径。大多数情况下,这与您放入 Tomcat 'webapps' 目录的 war 文件的名称完全匹配。您可以通过查看“webapps”目录来查看名称。您的 war 文件现在可能也已扩展到一个目录中。

由于您已将 finalName 放入 maven 构建部分,因此您的 war 文件应命名为:refms.war,因此您的应用程序将在以下位置运行:

http://host:port/refms/

我的假设是您在将 war 文件复制到 tomcat 之前没有将它重命名为 ROOT.war,因此您的应用程序将不会运行在: p>

http://host:port/

如果您这样做,您的应用程序将类似于嵌入式 Tomcat 实例运行;在根上下文中。

从您的日志文件中,我可以看到您的身份验证端点映射到 /refms/

Mapping servlet: 'dispatcherServletRegistration' to [/refms/*]

这与您的应用程序的上下文根相关。 因此,如果您没有重命名您的 war 文件,您收到 404 的身份验证端点可能会位于:

http://localhost:8080/refms/refms/api/account/authenticate

【讨论】:

以上是关于Spring Boot REST Controller 部署在外部 tomcat 9 服务器上时返回 404的主要内容,如果未能解决你的问题,请参考以下文章

列出所有已部署的 REST 端点(spring-boot、tomcat)

初入spring boot(八 )Spring Data REST

Spring Boot测试中使用REST Assured(转)

spring boot开发REST接口

Spring Boot 2 Rest Api Example

如何在 Spring(Boot)中装饰 REST 响应?