在 JAX-RS (CXF) 服务和 TomEE 7.0.1 中使用 EJB

Using EJBs in a JAX-RS (CXF) service and TomEE 7.0.1

我正在尝试执行以下操作(很多细节,抱歉...):

使用 @EJB 的 jax-rs 服务以避免 jndi 查找。像

@Path("rest/my-path)
public class Service {

  @EJB
  private MyEJB me;

  @Path("foo")
  @GET
  public String foo() {
    return me.foo();
  }
}

使用CXFNonSpringJaxrsServlet并限制url-pattern。 web.xml 应该是这样的:

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
    <init-param>
        <param-name>jaxrs.serviceClasses</param-name>
        <param-value>
            com.example.Service
        </param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

所以理论上 http://localhost:8080/my-app/rest/my-path/foo 会调用,你猜对了,foo()

TomEE 的日志支持这个:

Setting the server's publish address to be / REST Application:

http://localhost:8080/my-app/

URI: http://localhost:8080/my-app/rest/my-path

GET http://localhost:8080/my-app/rest/my-path/foo

但实际上,servlet 映射和 jaxrs 解析器的结合使得

http://localhost:8080/my-app/rest/my-path/foo return 404

and(注意双/rest/rest/)

http://localhost:8080/my-app/rest/rest/my-path/foo 实际上调用了该方法,但是 MyEJB 为 null

未找到 servlet 映射和服务路径以及 jaxrs.address 的任何组合,使根 url return 成为 index.html 和正确的服务 url 正在调用 foo 并且 MyEJB 不为空

有什么解决办法吗?

从您的 web.xml 中删除此内容:

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
    <init-param>
        <param-name>jaxrs.serviceClasses</param-name>
        <param-value>
            com.example.Service
        </param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

TomEE 会自动扫描您的应用程序并添加任何 REST 控制器。在启动期间,日志将包含您的 REST url 的路径。您可能需要像这样添加 Application.class

@ApplicationPath("/rest-prefix")
public class ApplicationConfig extends Application {
    public Set<Class<?>> getClasses() {
        return new HashSet<Class<?>>(Arrays.asList(Service.class));
    }
}