我正在尝试在我的一个RESTful服务中注入EJB 3.1。我已经关注了帖子:Inject an EJB into JAX-RS (RESTful service)并尝试了除构建注入提供程序之外的所有选项。我正在尝试的当前解决方案使用sd_cancel
和@RequestScoped
的组合,但我注入的bean变量仍为@Inject
。我在null
文件夹中有一个beans.xml
。
如何将EJB注入我的REST服务类?
UserService
/WEB-INF
ApplicationBean中
@Local
@Path("user/v1")
@Produces(MediaType.APPLICATION_JSON)
public class UserServiceV1 implements SystemLogger {
@Inject
private ApplicationBean appBean;
@GET
@Path("pingbean")
@Produces(MediaType.APPLICATION_JSON)
public Response pingAppBean() {
if(appBean == null) {
return Response.status(Response.Status.UNAUTHORIZED).entity("{\"faild\": \"App bean is null\"}").build();
}
String message = appBean.getHello();
return Response.status(Response.Status.OK)
.entity(message)
.build();
}
}
驻留在jar模块中,是具有业务逻辑的标准类。
SystemHandler
JAX-RS配置
@Stateless
@Local
public class ApplicationBean implements ApplicationBeanLocal {
@Override
public String getHello() {
return "Hello from ApplicationBean";
};
}
异常
@ApplicationPath("service")
public class ApplicationService extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<>();
resources.add(UserServiceV1.class);
resources.add(ApplicationBean.class);
resources.add(CorsFilterProvider.class);
return resources;
}
}
Resteasy / JAX-RS 我根据the documentation
添加了一个用于重新安装的CDI实现14:07:01,230 ERROR [io.undertow.request] UT005023: Exception handling request to /MyApp/service/user/v1/login: org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) [resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final]
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212) [resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final]
编辑:更改了问题和标题中的代码详细信息
答案 0 :(得分:0)
EJB 3.1意味着Java EE 6容器实现。 Java EE 6意味着JAX-RS 1.1。
JAX-RS 1.1仅需要支持@EJB注入企业java bean。
Java EE 7实现中提供的JAX-RS 2.0支持@Inject for EJB。
答案 1 :(得分:0)
正如Steve C回答的那样,在JAX-RS 1.1中注入EJB的正确方法是使用javax.ejb.EJB注释。 REST服务也必须是一个EJB才能使其工作。因此,您必须使用javax.ejb.Stateless注释而不是javax.enterprise.context.RequestScoped。
最终结果如下:
@Stateless
@Path("user/v1")
public class UserServiceV1 implements SystemLogger {
@EJB
private ApplicationBean appBean;
//etc.
}
您的更新代码未部署。要么ApplicationBean
实现ApplicationBeanLocal
并注入接口,要么不实现它并直接注入类。经过纠正,我设法运行你的例子。
此外,在ApplicationService
中,您无需添加ApplicationBean.class
。您只在那里注册REST根资源和功能提供程序。 @Local
类中也不需要UserServiceV1
,它不是EJB。
此外,它是beans.xml
,而不是bean.xml
(但此CDI 1.1上不再需要此文件)。
请参阅下面的测试代码:
jar模块的 pom.xml
依赖项:
<dependencies>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>javax.ejb-api</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
ApplicationBeanLocal.java
:
public interface ApplicationBeanLocal {
String getHello();
}
ApplicationBean.java
:
@Stateless
@Local
public class ApplicationBean implements ApplicationBeanLocal {
@Override
public String getHello() {
return "Hello from ApplicationBean";
}
}
JAX-RS应用程序的 pom.xml
依赖项:
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.14.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<version>3.0.14.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<!-- The jar-module containing ApplicationBean and ApplicationBeanLocal -->
<dependency>
<groupId>test</groupId>
<artifactId>testjar</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
TestApplication.java
:
@ApplicationPath("service")
public class TestApplication extends Application {
private final Set<Class<?>> resources = new HashSet<>();
public TestApplication() {
resources.add(UserServiceV1.class);
}
@Override
public Set<Class<?>> getClasses() {
return resources;
}
}
UserServiceV1.java
@Path("user/v1")
@RequestScoped
@Produces(MediaType.APPLICATION_JSON)
public class UserServiceV1 {
@Inject // Note that I'm referencing the interface, not the implementation
private ApplicationBeanLocal appBean;
@GET
@Path("pingbean")
@Produces(MediaType.APPLICATION_JSON)
public Response pingAppBean() {
final String message = appBean.getHello();
return Response.status(Response.Status.OK).entity(message).build();
}
}