Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将EJB注入JAX-RS(RESTful服务)_Java_Rest_Jakarta Ee_Ejb_Jax Rs - Fatal编程技术网

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

Java 将EJB注入JAX-RS(RESTful服务),java,rest,jakarta-ee,ejb,jax-rs,Java,Rest,Jakarta Ee,Ejb,Jax Rs,我正试图通过注释将无状态EJB注入我的JAX-RS Web服务。不幸的是,EJB只是null,当我尝试使用它时,我得到了NullPointerException @Path("book") public class BookResource { @EJB private BookEJB bookEJB; public BookResource() { } @GET @Produces("application/xml") @Path(

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

@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
  • Netbeans 6.9 RC 2
  • Java EE 6

你们能给我举个例子吗

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

选项1:使用注入提供者SPI

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

    @Inject
    private BookEJB bookEJB;

    //...
}
实现一个执行查找和注入EJB的提供程序。见:

jersey:jersey服务器: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;
        }
    }
}
见:

选项3:使用CDI

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

    @Inject
    private BookEJB bookEJB;

    //...
}
见:


不幸的是,我的答案太长,无法发表评论,所以这里是:

Zeck,我希望您知道,按照Pascal的建议,通过将bean升级到EJB,您正在做什么。不幸的是,尽管现在JavaEE很容易“将一个类变成EJB”,但您应该知道这样做的含义。每个EJB都会产生开销以及它提供的附加功能:它们是事务感知的,有自己的上下文,它们参与整个EJB生命周期,等等

我认为对于一种干净且可重用的方法,您应该做的是:将对服务器服务的访问(希望通过:)提取到一个。这个委托应该使用某种JNDI查找(可能是的,它们在JavaEE中仍然有效!)来访问您的后端

好的,私下说:如果你真的,真的,真的需要注入,因为你不想手动编写JNDI访问,你仍然可以让你的委托成为一个EJB,尽管它。。。嗯,只是感觉不对
这样,如果您决定切换到JNDI查找方法,那么以后至少可以很容易地用其他方法替换它。

您应该能够在JAX-RS资源中进行注入,而无需使用EJB或CDI组件。但是您必须记住,您的JAX-RS资源不能是单例的

因此,您可以使用此代码设置应用程序。这使得BookResource每个请求JAX-RS资源

@javax.ws.rs.ApplicationPath("application")
public class InjectionApplication extends javax.ws.rs.core.Application {
  private Set<Object> singletons = new HashSet<Object>();
  private Set<Class<?>> classes = new HashSet<Class<?>>();

  public InjectionApplication() {
    // no instance is created, just class is listed
    classes.add(BookResource.class);
  }

  @Override
  public Set<Class<?>> getClasses() {
    return classes;
  }

  @Override
  public Set<Object> getSingletons() {
    return singletons;
  }
}
@javax.ws.rs.ApplicationPath(“应用程序”)
公共类注入应用程序扩展了javax.ws.rs.core.Application{
private Set singleton=new HashSet();
私有集>();
公共注入应用程序(){
//没有创建实例,只列出了类
添加(booksource.class);
}
@凌驾

public Set我也有同样的问题,我通过上下文查找调用te EJB解决了它(注入是不可能的,我有相同的错误NullPointerException)。

这个线程很旧,但我昨天刚刚解决了同样的问题。以下是我的解决方案:

只需在类级别将BookResource设置为托管bean即可

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

<?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与EJB打包,则将其放入META-INF中

如果您想使用@EJB,那么就完成了。如果您想通过@inject注入EJB,那么必须将beans.xml也放入ejbs jar文件的META-INF中

你在做什么:你只是告诉容器,资源应该由容器管理。因此,它支持注入和生命周期事件。因此,你有了你的业务外观,而没有将它升级到EJB

您无需扩展javax.ws.rs.core.Application即可实现此功能。BookResource作为根资源自动确定请求范围

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


愉快的编码。

我也在尝试做同样的事情。我正在使用EJB3.1,并将我的应用程序作为EAR部署到单独的EJB项目中。正如Jav_Rock指出的,我使用上下文查找

@Path("book")
public class BookResource {

  @EJB
  BookEJB bookEJB;

  public BookResource() {
    try {
        String lookupName = "java:global/my_app/my_ejb_module/BookEJB";
        bookEJB = (BookEJB) InitialContext.doLookup(lookupName);
    } catch (NamingException e) {
        e.printStackTrace();
    }
  }

  @GET
  @Produces("application/xml")
  @Path("/{bookId}")
  public Book getBookById(@PathParam("bookId") Integer id) {
    return bookEJB.findById(id);
  }
}
有关非常有用的JNDI查找提示,请参见下面的链接


Arjan是对的。我创建了另一个类来初始化EJB,而不是为RS创建bean

@Singleton
@LocalBean
public class Mediator {
    @EJB
    DatabaseInterface databaseFacade;
要避免使用空指针,请执行以下操作:

@Path("stock")
public class StockResource {
    @EJB
    DatabaseInterface databaseFacade;
...

它实际上在GF

Errr上起作用,这是当你没有完全阅读问题时得到的结果。在你的RESTful服务的情况下,可以说,服务本身就是你的BusinessDelegate。所以你有了它:我陈述的第一部分和最后一部分仍然完全有效,而我可能不会为业务创建BusinessDelegatessDelegate…:)我也不喜欢让我的api端点成为EJB,但你可以只使用@ManagedBean。如果你喜欢,请看我的答案,你提供的JNDI是在
选项1:使用注入提供程序SPI
示例中开发的。人们经常谈论EJB“开销”似乎它们是重量级的,这是一个公认的事实,但大多数开发人员从未费心去衡量它。Adam Bien表明,2008年EJB和POJO之间的性能差异很小(<10%),此后性能才有所提高。简言之,如果您试图通过比较POJO和EJB来优化应用程序的性能,那么您找错了地方。我认为您误解了10%的数字,LeChe。这不是“我的应用程序现在慢了10%”,这是应用程序中速度慢10%的一种特定类型的操作。使用EJB而不是POJO不会使网络、数据库、文件IO和渲染多花费10%的时间,而且这些操作占了许多系统的大部分。在实际应用程序中使用EJB与POJO相比,对整体性能的影响可能可以忽略不计。至于latte在您的评论中,我同意有很好的理由不让所有东西都成为EJB:幸运的是,Pascal建议了两种选择。亲爱的@Pascal Thivent,让JAX资源成为
@无状态的
是唯一的出路吗?@Pascal选项3也可以像这样
@Path("stock")
public class StockResource {
    @EJB
    DatabaseInterface databaseFacade;
...