Java+Maven+Embedded Tomcat:项目拒绝识别网页

May*_*air 5 html java tomcat http-status-code-404 embedded-tomcat-7

我一直试图通过Apache Tomcat嵌入到应用程序中来使我的 Java 应用程序托管一个网页(一个 HTML 页面,而不是 JSP)。我使用Maven了在构建系统NetBeans IDE 8.0.2.出于某种原因,Tomcat拒绝承认index.html我已经放置在应用程序页面,尽管多次尝试和创建各种文件夹一样的WEB-INF。但它仍然404向我抛出错误。

这是我在我的项目中设置的一些相关代码(一些代码已被省略但与情况无关):

1. MainApplication.java - 启动 Tomcat

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.io.*;
import java.util.Optional;
import org.apache.catalina.startup.Tomcat;

public class MainApplication{

    public static final Optional<String> port = Optional.ofNullable(System.getenv("PORT"));

    public static void main(String[] args) throws Exception {
        String contextPath = "/";
        String appBase = ".";
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(Integer.valueOf(port.orElse("8080")));
        tomcat.getHost().setAppBase(appBase);
        tomcat.addWebapp(contextPath, appBase);
        tomcat.start();
        tomcat.getServer().await();
    }
}
Run Code Online (Sandbox Code Playgroud)

2. ShuttleServlet.java

@WebServlet(
            name = "ShuttleServlet", urlPatterns = {"/shuttle"}
    )

public class ShuttleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Code to interact with application to be added later
    } 
Run Code Online (Sandbox Code Playgroud)

3. 目录结构

- src
|
 - main
 |
  - resources
  - webapp
  |
    * index.html
    * scripts.js
Run Code Online (Sandbox Code Playgroud)

4. Maven 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</groupId>
    <artifactId>TransportApp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper-el</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jsp-api</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <tomcat.version>7.0.57</tomcat.version>
    </properties>
    <build>
  <finalName>TransportApp</finalName>
  <resources>
      <resource>
          <directory>src/main/webapp</directory>
          <targetPath>META-INF/resources</targetPath>
      </resource>
  </resources>
  <plugins>
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.3.2</version>
          <inherited>true</inherited>
          <configuration>
              <source>1.8</source>
              <target>1.8</target>
          </configuration>          
      </plugin>      
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <configuration>
              <descriptorRefs>
                  <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <finalName>TransportApp-${project.version}</finalName>
              <archive>
                  <manifest>
                      <mainClass>com.example.TransportApp.MainApplication</mainClass>
                  </manifest>
              </archive>
          </configuration>
          <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                      <goal>single</goal>
                  </goals>
              </execution>
          </executions>
      </plugin>     
  </plugins>
</build>            
</project>
Run Code Online (Sandbox Code Playgroud)

5.Tomcat控制台日志

Dec 04, 2016 3:09:24 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Dec 04, 2016 3:09:24 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Dec 04, 2016 3:09:24 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.57
Dec 04, 2016 3:09:24 AM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
INFO: No global web.xml found
Dec 04, 2016 3:09:25 AM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [170] milliseconds.
Dec 04, 2016 3:09:25 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Run Code Online (Sandbox Code Playgroud)

404尽管多次尝试和现在删除的文件夹,所有这些都会导致一个持久化。我希望所有这些都有助于找到罪魁祸首。

Kla*_*aek 0

第一个 Maven 已经旧了,请使用 Gradle 代替;)

每个进程都有一个工作目录,当文件是相对的时,它将根据该目录进行解释。理解这一点很重要,因为除非您将其用于简单测试,否则开发和部署之间的目录结构可能不同。

如果你将程序构建为 jar 文件,像“./src/main/webapp”这样的相对 URL 很可能不起作用,因为“src/main”会消失,只留下“webapp”(就像当你构建一个WAR 文件)。

构建像 Gradle(和 Maven)这样的工具,并且您的 IDE 在编译后有一个“processResource”步骤,它将资源复制到(通常)成为类路径一部分的位置。由于除非您正在构建 Web 应用程序,否则不会复制 /main/resources/webapp,因此在 IDE 之外运行代码时将会遇到问题。

就我个人而言,我建议您构建一个 Spring boot 应用程序,该应用程序已经嵌入了 tomcat。在 Spring Boot 中,.html 文件是从类路径(main/resources/static)加载的,并且由于资源位于类路径内,因此它们在开发和部署中将具有相同的位置(因为资源处理)。

对于 Spring Boot Web 应用程序,您将需要一个依赖项 org.springframework.boot:spring-boot-starter-web:1.4.1.RELEASE 所以您的build.gradle文件将如下所示(您可以在 IDE 中创建一个 Gradle 项目)

apply plugin: 'java'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.4.1.RELEASE")
}
Run Code Online (Sandbox Code Playgroud)

你的 Java Main 看起来像这样

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

将 .html 文件放入 /main/resources/static - 完成!正如您可能猜到的那样,Spring Boot 内部有很多魔力,而您不必编写更多代码的原因是因为 Spring Boot 团队选择了非常好的默认值,但如果您需要,请不要担心以后再进阶,这也是可能的。如果您需要服务器端渲染,您可以添加 org.springframework.boot:spring-boot-starter-thymeleaf:{version} ,并将模板放入 /resources/templates 中,然后就可以了。那里有很多很好的教程。

Spring 在 servlet 之上还有一个更好的抽象,称为控制器,同样有大量文档。

  • 当他问起一个独立的、嵌入 Tomcat 和 Maven 的问题时,你为什么要回答一些 Gradle + Spring Boot 代码? (3认同)