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

时间:2016-12-03 21:44:32

标签: java html 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();
    }
}

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
    } 

3。目录结构

- src
|
 - main
 |
  - resources
  - webapp
  |
    * index.html
    * scripts.js

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>

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

所有这些导致404尽管有多次尝试和现在已删除的文件夹仍然存在。我希望所有这些都有助于找到罪魁祸首。

5 个答案:

答案 0 :(得分:2)

问题的根本原因:

问题在于您的Launcher类。在启动器类中,下面的代码行试图查看web-app的同一目录,这实际上是不正确的。

 tomcat.addWebapp(contextPath, appBase);

由于appBase设置为&#34;。&#34;,这意味着它将尝试查看启动器类所在的同一目录。

<强>解决方案

尝试使用下面的代码,这很容易理解。您必须将webApp路径正确设置为tomcat上下文,以便在运行时点击该路径时识别它。

    String webappDirLocation = "src/main/webapp/";
    Tomcat tomcat = new Tomcat();

    //The port that we should run on can be set into an environment variable
    //Look for that variable and default to 8080 if it isn't there.
    String webPort = System.getenv("PORT");
    if(webPort == null || webPort.isEmpty()) {
        webPort = "8080";
    }

    tomcat.setPort(Integer.valueOf(webPort));

    StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
    System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath());

    // Declare an alternative location for your "WEB-INF/classes" dir
    // Servlet 3.0 annotation will work
    File additionWebInfClasses = new File("target/classes");
    WebResourceRoot resources = new StandardRoot(ctx);
    resources.addPreResources(new DirResourceSet(resources, "/WEB-     INF/classes", additionWebInfClasses.getAbsolutePath(), "/"));
    ctx.setResources(resources);

    tomcat.start();
    tomcat.getServer().await();

答案 1 :(得分:1)

第一个maven是旧的,改为使用Gradle;)

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

如果您将程序构建为jar文件,则“./src/main/webapp”之类的相对URL很可能无法正常工作,因为“src / main”会消失,只会留下“webapp”(如同你建立一个WAR文件。)

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

就个人而言,我建议您构建一个已经有嵌入式tomcat的Spring启动应用程序。在Spring Boot中.html文件是从类路径(main / resources / static)加载的,因为资源在类路径中,所以它们在开发和部署中都具有相同的位置(因为资源处理)。

对于Spring boot Web应用程序,您将需要一个依赖项 org.springframework.boot:弹簧引导起动网: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")
}

您的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);
    }
}

把你的.html文件放在/ main / resources / static中 - 完成!! 你可能会猜到Spring启动内部有很多魔法,而且你不必编写任何代码的原因是因为Spring Boot团队选择了非常好的默认值,但是如果你需要,不要担心以后更高级这也是可能的。如果你需要服务器端渲染,你可以添加org.springframework.boot:spring-boot-starter-thymeleaf:{version},并将你的模板放到/ resources / templates中,然后你去。那里有很多很好的教程。

Spring在servlet之上也有一个更好的抽象,称为控制器,再次提供大量文档。

答案 2 :(得分:0)

尝试使用SpringBoot!哪个有嵌入式tomcat, 使用web和thymeleaf依赖, thymeleaf是模板引擎,可以识别您的网页。 尝试从这个网站http://start.spring.io/创建一个spring boot项目,这是一个spring初始化程序,用于创建一个带有spring boot的maven项目。添加web和thymeleaf依赖项并生成项目。 将项目作为maven项目导入IDE中的项目, 或使用Spring工具套装

DemoApplication.java

 @Controller
 @SpringBootApplication
 public class DemoApplication {
     public static void main(String[] args) {
         SpringApplication.run(DemoApplication.class, args);
     }  
     @RequestMapping(value = "/homepage" , method = RequestMethod.GET  )
     public String sample()
     {
         return "home";

     }
}

的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>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.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.7</java.version>
</properties>
<dependencies>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</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-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
    </build>
    </project>

home.html的

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8"></meta>
 <title>HomePage</title>
 </head>
 <body>
 <h1>MY Spring Boot Home Page</h1>
 </body>
 </html>

答案 3 :(得分:0)

我认为您缺少主机名部分以及maven构建步骤。尝试使用maven命令和java -jar命令运行。尝试以下看看是否有效。

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

public static void main(String[] args) throws Exception {
    String contextPath = "/" ;
    String appBase = ".";
    Tomcat tomcat = new Tomcat();   
    tomcat.setPort(Integer.valueOf(PORT.orElse("8080") ));
    tomcat.setHostname(HOSTNAME.orElse("localhost"));
    tomcat.getHost().setAppBase(appBase);
    tomcat.addWebapp(contextPath, appBase);
    tomcat.start();
    tomcat.getServer().await();
}

执行以下步骤:(您需要在本地安装maven) 打开cmd,转到源文件夹,pom文件所在的位置。执行以下命令

  

mvn compile

然后按回车

  

mvn package。

然后按回车

  

cd目标   然后按回车

     

java -jar [你的应用名称] .jar(在目标文件夹中你会看到一个jar文件,把它的名字放在这里)

从命令运行后,您可以通过浏览器中的localhost浏览。 Netbeans跑了给我404.我这样解决了。

您可以查看此链接“运行Web应用程序部件”: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/basic_app_embedded_tomcat/basic_app-tomcat-embedded.html

答案 4 :(得分:0)

我不知道你是否解决了这里描述的问题。 我希望这会有助于其他人。 为了嵌入Tomcat,我使用了一个插件而不是依赖项:dowing so,所以,不需要主类和代码来创建一个tomcat实例。
以下是POM必须包含的内容:

<project ...>
  .....
  <dependencies>
    <!-- no need of any --->
  </dependencies>
  <build>
     <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>                    
                <server>localhost</server>
                <path>/${project.build.finalName}</path>
            </configuration>
        </plugin>

    </plugins>
  </build>
</project>

以下是web.xml的示例

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">


   <display-name>My Test App</display-name>
   <description>A test app</description>

   <welcome-file-list>
      <welcome-file>index.html</welcome-file>
   </welcome-file-list>

   <session-config>
     <session-timeout>30</session-timeout>
   </session-config>
</web-app>

您既不需要主类也不需要代码(如问题中所示)。 我们当然需要显示页面,所以这里有一个index.html的例子(如web.xml中所述):

<html>
   <body>
      <h2>Hello World!</h2>
   </body>
</html>

在eclipse中:右键单击,运行“运行配置”,在“Maven Build”下添加“新启动配置”,设置Base目录并在“Goals”下输入:tomcat7:run。 而已! 你会得到:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] --------------------------------------------------------------------
[INFO] Building rest-with-jersey Maven Webapp 0.0.1-SNAPSHOT
[INFO] --------------------------------------------------------------------
[INFO] 
[INFO] >>> tomcat7-maven-plugin:2.2:run (default-cli) > process-classes @ rest-with-jersey >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ rest-with-jersey ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ rest-with-jersey ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] <<< tomcat7-maven-plugin:2.2:run (default-cli) < process-classes @ rest-with-jersey <<<
[INFO] 
[INFO] --- tomcat7-maven-plugin:2.2:run (default-cli) @ rest-with-jersey ---
[INFO] Running war on http://localhost:8080/rest-with-jersey
[INFO] Using existing Tomcat server configuration at /common/home/$$$/$$$$/lnx/workspace/rest-with-jersey/target/tomcat
[INFO] create webapp with contextPath: /rest-with-jersey
Sep 11, 2017 4:03:07 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Sep 11, 2017 4:03:07 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Sep 11, 2017 4:03:07 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.47
Sep 11, 2017 4:03:09 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]

In a browser with http://localhost:8080/rest-with-jersey/ you get the " Hello World!".