将 EJB 注入 JAX-RS(RESTful 服务)

2022-08-31 13:38:01

我正在尝试通过注释将无状态EJB注入到我的JAX-RS Web服务中。不幸的是,EJB只是,当我尝试使用它时,我得到了一个。nullNullPointerException

@Path("book")
public class BookResource {

    @EJB
    private BookEJB bookEJB;

    public BookResource() {
    }

    @GET
    @Produces("application/xml")
    @Path("/{bookId}")
    public Book getBookById(@PathParam("bookId") Integer id)
    {
        return bookEJB.findById(id);
    }
}

我做错了什么?

以下是有关我的机器的一些信息:

  • 玻璃鱼 3.1
  • 网豆 6.9 RC 2
  • Java EE 6

你们能举一些工作的例子吗?


答案 1

我不确定这是否应该有效。因此,要么:

选项 1:使用注入提供程序 SPI

实现一个将执行查找并注入 EJB 的提供程序。看:

com.sun.jersey:jersey-server:1.17 的示例:

import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.spi.inject.Injectable;
import com.sun.jersey.spi.inject.InjectableProvider;

import javax.ejb.EJB;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.ws.rs.ext.Provider;
import java.lang.reflect.Type;

/**
 * JAX-RS EJB Injection provider.
 */
@Provider
public class EJBProvider implements InjectableProvider<EJB, Type> {

    public ComponentScope getScope() {
        return ComponentScope.Singleton;
    }

    public Injectable getInjectable(ComponentContext cc, EJB ejb, Type t) {
        if (!(t instanceof Class)) return null;

        try {
            Class c = (Class)t;
            Context ic = new InitialContext();

            final Object o = ic.lookup(c.getName());

            return new Injectable<Object>() {
                public Object getValue() {
                    return o;
                }
            };
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

选项 2:使 BookResource 成为 EJB

@Stateless
@Path("book")
public class BookResource {

    @EJB
    private BookEJB bookEJB;

    //...
}

看:

选项 3:使用 CDI

@Path("book")
@RequestScoped
public class BookResource {

    @Inject
    private BookEJB bookEJB;

    //...
}

看:


答案 2

这个线程相当古老,但是我昨天遇到了同样的问题。这是我的解决方案:

只需在类级别通过@javax.annotation.ManagedBean 使 BookResource 成为托管 Bean 即可。

为此,您需要使用bean启用CDI.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

如果 BookResource 是 war 文件的一部分,则此文件需要位于 WEB-INF 中。如果 BookResource 与 ejbs 打包在一起,请将其放入 META-INF 中。

如果你想使用@EJB你就完成了。如果你想通过@Inject而不是bean来注入EJB.xml也必须放入EJbs jar文件中到META-INF中。

你正在执行的操作:你只是告诉容器,资源应该由容器管理。因此,它支持注入以及生命周期事件。因此,您拥有您的业务外观,而无需将其提升为 EJB。

您无需扩展javax.ws.rs.core.Application即可使其正常工作。BookResource 是作为根资源自动请求的作用域。

使用 Glassfish 3.1.2 和 maven 项目进行测试。

快乐编码。