尝试使用 Servlet 打包 REST 应用程序时如何修复 'cannot be cast to javax.servlet.Servlet' 错误

How to fix 'cannot be cast to javax.servlet.Servlet' error while trying to package REST App with Servlet

我正在尝试将 Angular 7 与基于 Maven 的后端 java 项目设置到单个 war 文件中。目前我正在尝试配置我目前遇到此问题的 web.xml 文件。我完全不确定我的方法是否有效或 'good' 因此我将首先描述我正在尝试做的事情(如果您在这方面认为更好,请纠正我)。
所以我有几个 JAX-RS classes,我想作为 REST API。为此,我创建了相应的 javax.ws.rs.core.Application classes 来提供这些 REST 组件。然后我将 Application class 包含在 web.xml 文件中。以下是文件:

web.xml

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

  <servlet>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <url-pattern>/rmz/*</url-pattern>
  </servlet-mapping>

我试过的 web.xml 的另一种变体

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

  <servlet>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>backend.backendservice.StammSolvaraJahrRestApplication</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>backend.backendservice.StammSolvaraJahrRestApplication</servlet-name>
    <url-pattern>/rmz/*</url-pattern>
  </servlet-mapping>

申请class

public class StammSolvaraJahrRestApplication extends Application {

  @Override
  public Set<Class<?>> getClasses() {
    Set<Class<?>> sets = new HashSet<>();
    sets.add(StammSolvaraJahrRest.class);
    return sets;
  }

}

我得到的错误是:java.lang.ClassCastException: backend.backendservice.StammSolvaraJahrRestApplication cannot be cast to javax.servlet.Servlet 如果我删除 <servlet-class> 那么我会得到 No servlet class has been specified for servlet。我正在关注 https://docs.oracle.com/cd/E24329_01/web.1211/e24983/configure.htm#RESTF183 and How to deploy a JAX-RS application? 等,但它似乎不起作用。

问题就是它所说的。 web.xml 中的这一行需要 javax.servlet.Servlet:

<servlet-class>backend.backendservice.StammSolvaraJahrRestApplication</servlet-class>

由于 Application 不是 javax.servlet.Servlet,您在 运行 处理 XML 文件时收到错误。

如果可以,我建议您从 Spring Boot starter 应用程序开始。 Spring Boot 会为您处理所有这一切。它甚至可以在 jar 文件中嵌入一个 Tomcat 服务器,这样你就可以 运行 你的服务器就像一个简单的 Java 应用程序。这样做会让你不必担心你在这里处理的是什么。

有两种方法可以定义您的 JAX-RS servlet。

1) 有了像你这样的应用程序子类,你可以跳过 web.xml 配置,只添加应用程序注释

@ApplicationPath("resources")
public class StammSolvaraJahrRestApplication extends Application

2) 使用 web.xml 配置

<servlet>
    <display-name>JAX-RS Servlet</display-name>
    <servlet-name>package.hierarchy.StammSolvaraJahrRestApplication</servlet-name>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>package.hierarchy.StammSolvaraJahrRestApplication</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>JaxRSServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

如果您跳过最后一个 servlet 映射,它将使用您的 @ApplicationPath 指定值,或者 "/resources" 如果缺少前一个。