问题描述
我正在尝试将EJB 3.1注入我的RESTful服务之一。我遵循了这个职位:,并尝试所有选项,除了构建注入提供程序。我正在尝试的当前解决方案使用 @RequestScoped
和 @Inject
的组合,但是我注入的bean变量仍然是空
。我在 / WEB-INF
文件夹中有一个 beans.xml
。 如何将EJB注入到我的REST服务类中?
UserService
@Local
@Path(user / v1)
@Produces(MediaType.APPLICATION_JSON)
public class UserServiceV1实现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\)
}
String message = appBean.getHello();
return Response.status(Response.Status.OK)
.entity(message)
.build();
}
}
ApplicationBean
SystemHandler
驻留在jar模块中,是具有业务逻辑的标准类。
@Stateless
@Local
public class ApplicationBean实现ApplicationBeanLocal {
@Override
public String getHello(){
返回来自ApplicationBean的Hello;
};
}
JAX-RS配置
@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);
返回资源;
}
}
异常
14:07:01,230 ERROR [io.undertow.request] UT005023:异常处理请求到/ MyApp / service / user / v1 / login:org.jboss.resteasy。 spi.UnhandledException:java.lang.NullPointerException
在org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)[resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final ]
在org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212)[resteasy-jaxrs-3.0.14.Final.jar:3.0.14.Final]
Resteasy / JAX-RS
我已经根据
<依赖性>
< groupId> org.jboss.resteasy< / groupId>
< artifactId> resteasy-jaxrs< / artifactId>
< version> 3.0.14.Final< / version>
< scope>已提供< / scope>
< / dependency>
<依赖关系>
< groupId> org.jboss.resteasy< / groupId>
< artifactId> resteasy-cdi< / artifactId>
< version> 3.0.14.Final< / version>
< scope>已提供< / scope>
< / dependency>
编辑:更改问题标题中的代码详细信息
正如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实现SystemLogger {
@ EJB
private ApplicationBean appBean;
//等。
}
编辑
您更新的代码未部署。要么有 ApplicationBean
实现 ApplicationBeanLocal
并注入接口,或者不实现它并直接注入该类。有了这个更正,我设法运行你的例子很好。
另外,在 ApplicationService
中,你不需要添加 ApplicationBean.class
。您只注册REST根资源和功能提供商。 @Local
在 UserServiceV1
类中也是不必要的,它不是EJB。
此外,它是 beans.xml
,而不是 bean.xml
(但是这个文件不是必需的
请参阅下面的测试代码:
pom。 xml
jar模块的依赖项:
<依赖关系>
<依赖关系>
< 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实现ApplicationBeanLocal {
@Override
public String getHello(){
返回来自ApplicationBean的Hello;
}
}
pom.xml
JAX-RS应用程序的依赖关系:
<依赖关系>
<依赖关系>
< groupId> org.jboss.resteasy< / groupId>
< artifactId> resteasy-jaxrs< / artifactId>
< version> 3.0.14.Final< / version>
< scope>已提供< / scope>
< / dependency>
<依赖关系>
< groupId> org.jboss.resteasy< / groupId>
< artifactId> resteasy-cdi< / artifactId>
< version> 3.0.14.Final< / version>
< scope>已提供< / scope>
< / dependency>
<依赖关系>
< groupId> javax.enterprise< / groupId>
< artifactId> cdi-api< / artifactId>
< version> 1.2< / version>
< scope>已提供< / scope>
< / dependency>
<! - 包含ApplicationBean和ApplicationBeanLocal的jar模块 - >
<依赖关系>
< 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(){
返回资源;
}
}
UserServiceV1.java
@Path(user / v1)
@RequestScoped
@Produces (MediaType.APPLICATION_JSON)
public class UserServiceV1 {
@Inject //请注意,我引用了接口,而不是实现
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();
}
}
I am trying to inject and EJB 3.1 in one of my RESTful services. I've followed the post: Inject an EJB into JAX-RS (RESTful service) and tried all options except building an injection provider. The current solution that I am trying uses a combination of @RequestScoped
and @Inject
, but my injected bean variable is still null
. I have a beans.xml
in the /WEB-INF
folder.
How can I inject an EJB into my REST service class?
UserService
@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();
}
}
ApplicationBeanThe SystemHandler
resides in jar module and is a standard class with business logic.
@Stateless
@Local
public class ApplicationBean implements ApplicationBeanLocal {
@Override
public String getHello() {
return "Hello from ApplicationBean";
};
}
JAX-RS configuration
@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;
}
}
Exception
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]
Resteasy /JAX-RSI've added a CDI implementation for resteasy according to the documentation
<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>
EDIT: changed code details in the question and title
As Steve C answered, the proper way to inject an EJB in JAX-RS 1.1 is with the javax.ejb.EJB annotation. The REST service must also be an EJB for this to work. As such, you have to use the javax.ejb.Stateless annotation instead of javax.enterprise.context.RequestScoped.
The end result is as follows:
@Stateless
@Path("user/v1")
public class UserServiceV1 implements SystemLogger {
@EJB
private ApplicationBean appBean;
//etc.
}
EDIT
Your updated code doesn't deploy. Either have ApplicationBean
implement ApplicationBeanLocal
and inject the interface, or don't implement it and inject the class directly. With that corrected, I managed to run your example just fine.
Also, in ApplicationService
, you don't need to add ApplicationBean.class
. You only register there REST root resources and feature providers. @Local
is also unnecessary in the UserServiceV1
class, it's not an EJB.
Furthermore, it's beans.xml
, not bean.xml
(but this file is not necessary anymore from CDI 1.1 on).
See my testcode below:
pom.xml
dependencies for the jar module:
<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";
}
}
pom.xml
dependencies for the JAX-RS application:
<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();
}
}
这篇关于当将企业bean注入JAX-RS 2.0 REST服务时,NullPointerException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!