简体   繁体   English

在访问资源时将Spring Boot WAR部署到Tomcat 8 - HTTP 404

[英]Deploying Spring Boot WAR to Tomcat 8 - HTTP 404 when accessing resources

I'm new to Spring Boot and struggling to deploy a simple HTML web app (AngularJS) to Tomcat 8. This web app simply serves some HTML/CSS/JS content with no REST calls to a backend. 我是Spring Boot的新手,并且正在努力将一个简单的HTML Web应用程序(AngularJS)部署到Tomcat 8.这个Web应用程序只是提供一些HTML / CSS / JS内容而没有对后端的REST调用。 It has been "compiled" using Webpack -- this produces JS/CSS bundles and a single index.html file that points to them via <script> / <link> tags -- and has been tested on ExpressJS and Spring Boot w/ Embedded tomcat and works as expected. 它已经使用Webpack进行“编译” - 这会生成JS / CSS包和一个通过<script> / <link>标记指向它们的index.html文件 - 并且已经在ExpressJS和Spring Boot w / Embedded上进行了测试tomcat并按预期工作。 But going down the path of a stand-alone WAR and deploying to Tomcat 8 does not seem to work properly. 但是沿着独立WAR的路径并部署到Tomcat 8似乎不能正常工作。

For the Spring Boot project, I've included all the HTML/CSS/JS files in the src/main/resources/public folder (no subfolders) and have also configured the pom.xml as follows (basic config): 对于Spring Boot项目,我已将所有HTML / CSS / JS文件包含在src/main/resources/public文件夹(无子文件夹)中,并且还按如下方式配置了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.example.my-app</groupId>
    <artifactId>my-app</artifactId>
    <version>0.0.1</version>
    <packaging>war</packaging>

    <name>my-app</name>
    <description>Demo project for Spring Boot</description>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </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>
    </dependencies>

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

"Main" class: “主要”课程:

package com.example.my.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

@SpringBootApplication
public class MyAppApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyAppApplication.class);
    }

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

Here are the steps I used to do the Tomcat deployment: 以下是我用于执行Tomcat部署的步骤:

  1. mvn clean package to generate the WAR mvn clean package生成WAR
  2. Copy the WAR to path/to/tomcat8/webapp 将WAR复制到path / to / tomcat8 / webapp
  3. Start Tomcat 启动Tomcat
  4. http://localhost:8080/my-app => auto-loads index.html http:// localhost:8080 / my-app =>自动加载index.html

Unfortunately all I see are 404 errors because it couldn't find some JS/CSS file. 不幸的是我看到的都是404错误,因为它找不到一些JS / CSS文件。 Is there a config I'm missing? 有没有我失踪的配置?

Updated : Here is the index.html file (auto-generated via Webpack): 更新 :这是index.html文件(通过Webpack自动生成):

<!doctype html>
<html>
  <head>
    <base href="/">
    <meta charset="utf-8">
    <title>My App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="icon" type="image/png" href="./assets/images/favicon.ico" />
  <link href="/main-aa49893f83cc830596563d81f09a9611.css" rel="stylesheet"><link href="/main-5949f1f257a55a77e48bc4ab62fbc99a.css" rel="stylesheet"></head>

  <body ng-app="myapp">
    <ui-view></ui-view>
  <script type="text/javascript" src="vendor-353ddb48f4ffe6546d59.js"></script><script type="text/javascript" src="app-353ddb48f4ffe6546d59.js"></script></body>
</html>

Here are the errors I'm seeing in Chrome Web Inspector when visiting localhost:8080/my-app/index.html : 以下是我在访问localhost:8080/my-app/index.html时在Chrome Web Inspector中看到的错误localhost:8080/my-app/index.html

http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)

One more thing I forgot to mention. 还有一件事我忘了提。 When I generate the war using mvn clean package , all the files that are under src/main/resources/public are placed into the WEB-INF/classes/resource subfolder. 当我使用mvn clean package生成war时,src / main / resources / public下的所有文件都放在WEB-INF/classes/resource子文件夹中。 According to research, these files are not publicly visible (ie if I try to access localhost:8080/my-app/foo.css, it'll give 404). 根据研究,这些文件不是公开可见的(即如果我尝试访问localhost:8080 / my-app / foo.css,它将给出404)。 Is this why the index.html file is unable to "see" the JS/CSS files it depends on? 这就是index.html文件无法“看到”它依赖的JS / CSS文件的原因吗?

The most common issue with the setup you have described, without more context, is that you are most likely using absolute URLs to point at your js / css files. 在没有更多上下文的情况下,您所描述的设置的最常见问题是您最有可能使用绝对URL指向您的js / css文件。 As such when you put them into the servlet container under /my-app they no longer reference properly as they are trying to go to the root / . 因此,当您将它们放入/my-app下的servlet容器中时,它们不再正确引用,因为它们正在尝试转到根/ You need to use relative URLs when describing the location of the resource files on the path. 在描述路径上资源文件的位置时,需要使用相对URL。

I ended up figuring it out but not using Spring Boot to package the WAR file. 我最终搞清楚但没有使用Spring Boot打包WAR文件。 There was another project lying around on my local that used plain old Maven + pom.xml + web.xml to create WARs, which I used as a reference to figure out why the current project was not working. 我的本地还有另一个项目,它使用普通的旧Maven + pom.xml + web.xml来创建WAR,我将其用作参考,以找出当前项目无法正常工作的原因。 There were multiple issues: 存在多个问题:

  • When you deploy onto Tomcat 8 using default config, it will append the name of the WAR file (what they refer to as Context) to its path. 使用默认配置部署到Tomcat 8时,它会将WAR文件的名称(它们称为上下文)添加到其路径中。 In this case, it was http://localhost:8080/my-app . 在这种情况下,它是http://localhost:8080/my-app The "compiled" AngularJS app's index.html had a <base href="/"> tag that needed to point to /my-app/ instead of / . “已编译”的AngularJS应用程序的index.html有一个<base href="/">标记,需要指向/my-app/而不是/ This was the main reason why the JS/CSS files were not visible in Web Inspector > Sources . 这是在Web Inspector > Sources不到JS / CSS文件的主要原因。
  • <link> tag's src attribute was not supposed to contain a leading / <link>标签的src属性不应包含前导/
  • In the case of the Spring Boot App I posted above, it comes with an Embedded Tomcat and deploys the app at the Root Context so there's no need to change any paths in the index.html file. 对于我上面发布的Spring Boot App,它附带了一个嵌入式Tomcat,并在根上下文中部署应用程序,因此无需更改index.html文件中的任何路径。
  • Similar to Spring Boot, I also had no issues running the app in ExpressJS since a "sub-context" was not created. 与Spring Boot类似,我也没有在ExpressJS中运行应用程序的问题,因为没有创建“子上下文”。 Again, there was no need to modify any files in this case. 同样,在这种情况下无需修改任何文件。

There were other errors related to finding resources like .ttf files but at least the app was able to run. 还有其他与查找.ttf文件等资源相关的错误,但至少应用程序能够运行。

Update: Looks like its possible to serve the WAR file from the Tomcat 8 root by adding the following near the bottom of the server.xml file: 更新:看起来可以通过在server.xml文件底部附近添加以下内容来从Tomcat 8根目录提供WAR文件:

<Context path="" docBase="my-app" debug="0" reloadable="true"></Context>

This will prevent the need to modify the index.html file. 这样可以防止需要修改index.html文件。

Awesome :) 太棒了:)

I had the same problem, and it is related to Webpack more than to Spring-boot. 我有同样的问题,它与Webpack相关而不是Spring-boot。 In your webpack.common.js / webpack.prod.js you have to set : 在您的webpack.common.js / webpack.prod.js中,您必须设置:

metada.baseUrl = './';

and inject this in your <base> link in index.html 并将其注入index.html中的<base>链接

And you also have to set 你也必须设置

output.publicPath: './'

With both variable set, this worked for me. 有了这两个变量集,这对我有用。

Uhmm i've tried some of this on my spring-boot project. 嗯,我在spring-boot项目中试过了一些。

First i'd add a dependency on my project pom.xml 首先,我将对我的项目pom.xml添加一个依赖项

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

then i'd add an index.html on src/main/resources/templates 然后我在src/main/resources/templates上添加一个index.html

after that you should add a controller to point to that index 之后,您应该添加一个控制器以指向该索引

@Controller
public class AppController {

    @RequestMapping("/")
    String index() {
        return "index";
    }
}

For more information see this guide. 有关更多信息,请参阅本指南。 Spring-boot and Thymeleaf 弹簧靴和Thymeleaf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM