如何使用 CDI 和 JAX-RS 配置 Tomcat 9,Java EE7?

How to configure Tomcat 9 with CDI and JAX-RS, Java EE7?

我正在尝试实现简单的 java Rest 应用程序并将其部署到 Tomcat 服务器。 (Tomcat 是必需的,所以 Tomee 不是一个选项)

这是我项目的结构:

根内容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>org.example</groupId>
      <artifactId>tomcat-project</artifactId>
      <version>1.0-SNAPSHOT</version>
      <modules>
        <module>tomcat-rest</module>
        <module>tomcat-app</module>
      </modules>
      <packaging>pom</packaging>
    
      <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>
      </properties>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependencies>
        <dependency>
          <groupId>javax</groupId>
          <artifactId>javaee-api</artifactId>
          <scope>provided</scope>
        </dependency>
      </dependencies>
    
      <build>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <includes>
              <include>META-INF/*</include>
            </includes>
            <filtering>true</filtering>
          </resource>
        </resources>
      </build>
    </project>

tomcat的内容-其余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">
      <parent>
        <artifactId>tomcat-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
      <modelVersion>4.0.0</modelVersion>
    
      <artifactId>tomcat-rest</artifactId>
    </project>

tomcat-应用的内容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>

  <parent>
    <artifactId>tomcat-project</artifactId>
    <groupId>org.example</groupId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>tomcat-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <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>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.example</groupId>
      <artifactId>tomcat-rest</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>tomcat-app</finalName>

    <plugins>
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <version>1.7.13</version>
        <configuration>
          <container>
            <containerId>tomcat9x</containerId>
            <type>embedded</type>
          </container>
          <deployables>
            <deployable>
              <properties>
                <context>tomcat-app</context>
              </properties>
            </deployable>
          </deployables>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.openejb.maven</groupId>
        <artifactId>tomee-maven-plugin</artifactId>
        <version>1.7.1</version>
        <configuration>
          <tomeeVersion>1.7.1</tomeeVersion>
          <tomeeClassifier>plus</tomeeClassifier>
          <debugPort>7000</debugPort>
          <tomeeHttpPort>8080</tomeeHttpPort>
          <args>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7000</args>
          <debug>false</debug>
          <reloadOnUpdate>true</reloadOnUpdate>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

web.xml的内容:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

beans.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

RestApplication.java的内容:

package org.example.rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest")
public class RestApplication extends Application {
}

TestBean.java的内容:

package org.example.rest;

import javax.ejb.Stateless;

@Stateless
public class TestBean {
    public String test() {
        return "Test Bean";
    }
}

TestResource.java的内容:

package org.example.rest;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/test")
@Stateless
public class TestResource {

    @Inject TestBean testBean;
    @GET
    public String test() {
        return testBean.test();
    }
}

正如你在 tomee-app 中看到的那样 pom.xml 我已经配置了 Maven 插件 tomee-maven-plugincargo-maven2-plugin(容器设置为 tomcat9x)作为唯一的插件我发现的 maven 插件 运行 Tomcat 9.

使用 Tomee 一切正常,Jax-Rs 运行ning 和测试 bean 注入工作正常。

但是使用 Tomcat 我无法让 CDI 至少工作。我尝试了在 Tomcat、OpenWebBeans、Apache CXF 等上找到的几个选项。我总是以以太 Jax-Rs 结束,而不是 运行 注入不起作用。

我没有遇到 post 错误,因为我尝试了很多事情并最终遇到了一堆不同的错误。

我更喜欢使用 OpenWebBeans 和 Apache CXF,因为 Tomee 使用它们,但到目前为止找不到任何工作说明。

我尝试按照这些 instructions 获取 OpenWebBeans 运行 Tomcat 以及 Glassfish Jersey Containers,但我在注入 TestBean 时遇到错误。

您需要额外的依赖项、JAX-RS 实现和 CDI 实现。

例如:

<dependency>
  <!-- https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/modules-and-dependencies.html#servlet-app-general -->
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jersey.inject</groupId>
  <artifactId>jersey-hk2</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <!-- https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/cdi.support.html#cdi.support.existing.containers -->
  <groupId>org.glassfish.jersey.ext.cdi</groupId>
  <artifactId>jersey-cdi1x</artifactId>
  <version>${jersey.version}</version>
</dependency>
<dependency>
  <!-- https://docs.jboss.org/weld/reference/latest-3.1/en-US/html/environments.html#weld-servlet -->
  <groupId>org.jboss.weld.servlet</groupId>
  <artifactId>weld-servlet-core</artifactId>
  <version>${weld.version}</version>
</dependency>

然后,将javax.ejb.Stateless注释替换为javax.enterprise.context.RequestScoped,因为 javax.ejb.Stateless 注解不是 CDI 规范,而是 EJB 规范。


complete diff