首页 > 解决方案 > 将 SPA(并且没有 Java 代码)打包到 WAR 中时,如何为每个 URL 提供 index.html,除了那些与实际资产文件匹配的 URL?

问题描述

我有一个单页 web 应用程序,它在构建时必须可安装到 java-ee 应用程序服务器中,例如 Glassfish。也就是说,我应该把它打包成一个WAR。

这个单页 web 应用程序与其后端应用程序是高度分离的,它应该是可自行构建和部署的。也就是说,WAR 只应该并且将包括单页 web 应用程序。

如果可能的话,我想在没有任何 Java 代码的情况下解决这个问题。

在单页应用程序的情况下,URL 路由的功能应该是这样的:

  1. 如果请求的 URL 与静态资产文件(html、js、css 等)匹配,则应提供该文件。

  2. 在任何其他情况下,index.html都应该送达。

当第二点不适用时,应用程序(默认情况下)只能在其入口点 ( index.html) 访问。而不是直接指向任何子路由的 URL。

有一个解决方法,因为在 Ember.js 中,可以设置一个选项来使用基于哈希的子路由 URL。但这有其局限性,我想完全避免。

然而,我目前拥有的解决方案只能通过打开上述解决方法来工作。我正在使用 Maven 和maven-assembly-plugin来实现这一点。

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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>My App</name>
  <build>
    <finalName>finalName</finalName>
    <plugins>
      <plugin>
        <!-- assemble static content -->
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptors>
            <descriptor>static.xml</descriptor>
          </descriptors>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

静态的.xml

dist是 ember-cli 放置编译资产的目录,我需要包括在内。)

<?xml version="1.0" encoding="UTF-8"?>
<assembly>
  <id>static</id>
  <formats>
    <format>war</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <fileSets>
    <fileSet>
      <directory>dist</directory>
      <includes>
        <include>**</include>
      </includes>
      <excludes>
        <exclude>WEB-INF/*</exclude>
      </excludes>
      <outputDirectory>/</outputDirectory>
    </fileSet>
    <fileSet>
      <directory>WEB-INF</directory>
      <includes>
        <include>**</include>
      </includes>
      <outputDirectory>/WEB-INF</outputDirectory>
    </fileSet>
  </fileSets>
</assembly>

我在 WEB-INF 文件夹中也有一个 web.xml,但这基本上是空的。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">

</web-app>

所以总结一下这个问题:是否可以在不编写任何 Java 代码的情况下说路由逻辑,即没有任何“粘合”或“中间人”服务器端模块?

标签: mavenjakarta-eebuildsingle-page-applicationwar

解决方案


我可以让它工作(我的前端是有角度的,但它可以与任何其他人一起工作,只要它对返回状态 404 不挑剔)。我的 web.xml:

<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
  <error-page>
    <error-code>404</error-code>
    <location>/index.html</location>
  </error-page>
</web-app>

这意味着:当找不到资源时(不是servlet,或jsp,或静态文件或其他),则将“/index.html”作为404页面。

但是有两个缺点: 1. 任何你的应用程序碰巧询问而服务器没有的资源(无论是图像、样式表还是其他),都会得到一个完整的 /index.html 作为响应;2. 在 404 之后获得一个完全正常工作的应用程序可能会有点误导(对浏览器)。


推荐阅读