2016-04-15 72 views
0

我正在尝试将EJB 3.1注入到其中一个RESTful服务中。我遵循了这个帖子:Inject an EJB into JAX-RS (RESTful service)并尝试了除建立注入提供者之外的所有选项。我正在尝试的当前解决方案使用@RequestScoped@Inject的组合,但我注入的bean变量仍然是null。我在/WEB-INF文件夹中有一个beans.xml将企业bean注入JAX-RS 2.0 REST服务时出现NullPointerException

如何将EJB注入到我的REST服务类中?

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(); 
    } 
} 

ApplicationBean中 的SystemHandler驻留在罐子模块和是一个标准类的业务逻辑。

@Stateless 
@Local 
public class ApplicationBean implements ApplicationBeanLocal { 

    @Override 
    public String getHello() { 
     return "Hello from ApplicationBean"; 
    }; 
} 

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); 
     return resources; 
    } 
} 

异常

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-RS 我根据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> 
添加RestEasy的一个实施CDI

编辑:更改问题和标题中的代码详细信息

回答

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。

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根资源和功能提供者。 @LocalUserServiceV1类中也是不必要的,它不是EJB。

此外,它是beans.xml,而不是bean.xml(但该文件不再需要从CDI 1.1开始)。

见我testcode如下:

pom.xml依存关系的jar模块:

<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依赖的JAX-RS应用:

<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(); 
    } 
} 
+0

我使用@EJB注入其他项目豆类,我已经做了与JAX-RS 1.1。但我目前的项目使用JAX-RS 2.0,请参阅resteasy-jaxrs依赖项。明天将尽力解决问题,欢迎任何意见。 – Chris

+0

您使用的是什么应用程序服务器和版本?我假设JBoss EAP或Wildfly,因为你声明RestEasy而不是Jersey作为依赖。 – RafaelHamasaki

+0

如果您想使用RestEasy版本,而不是JBoss提供的版本(可能是较旧的JAX-RS 1.1兼容版本),您还必须从部署中排除该模块。 参见: [链接](https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6/html/Development_Guide/Exclude_a_Subsystem_from_a_Deployment.html) [链接](HTTPS://docs.jboss .org/author/display/WFLY8/Class + Loading + in + WildFly) – RafaelHamasaki