【问题标题】:Injecting EJB into JAX-RS REST controller将 EJB 注入 JAX-RS REST 控制器
【发布时间】:2014-06-30 20:01:42
【问题描述】:

我正在为一项任务构建一个 Java EE 应用程序。我需要使用 JPA 进行持久性,使用 EJB 来封装我的业务逻辑,以及使用 Web 界面进行演示。不允许使用弹簧。

我的应用程序由一个根 Maven 项目和 4 个 Maven 子项目组成:一个用于我的模型层(JPA 实体),一个用于我的业务层(EJB),一个用于我的表示层(Web 应用程序),一个用于建立一个耳朵。我正在将 EAR 部署到 Glassfish。

但是,我在将所有内容放在一起时遇到了一些问题。我的模型层(JAR 模块)中有一个实体类,如下所示:

@Entity
public class Product implements Serializable {
    @Id @GeneratedValue
    private int productId;

    ...
}

然后我在我的业务层(EJB 模块)中创建了一个服务 bean 来封装事务逻辑:

@Stateless
public class ProductService {
    @PersistenceContext( unitName = "DummyContext" )
    EntityManager em;

    public Product findById( int id ) {
        return em.find( Product.class, id );
    }

    public List<Product> getAll() {
        TypedQuery<Product> query = em.createQuery( "SELECT p FROM Product p", Product.class );
        return query.getResultList();
    }
}

最后,我在我的表示层(WAR 模块)中创建了一个 JAX-RS 控制器,我尝试使用 REST 访问我的产品服务。

JAX-RS 设置:

@ApplicationPath( "/api" )
public class ApplicationConfig extends javax.ws.rs.core.Application {
}

控制器:

@Path( "/products" )
public class ProductController {
    @Inject
    private ProductService productService;

    @Path( "/all" )
    @GET
    @Produces( "text/plain" )
    public String getAll() {
        return "Nothing interesting yet";
    }
}

如您所见,REST 控制器尚未执行任何操作。不过,这个例子现在失败了。部署后第一次尝试访问\api\products\all,抛出如下异常:

javax.servlet.ServletException: Servlet.init() for servlet wedvich.ApplicationConfig threw exception

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001409 Ambiguous dependencies for type [ProductService] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private wedvich.ProductController.productService]. Possible dependencies [[Session bean [class wedvich.ProductService with qualifiers [@Any @Default]; local interfaces are [ProductService], Session bean [class wedvich.ProductService with qualifiers [@Any @Default]; local interfaces are [ProductService]]]

org.jboss.weld.exceptions.DeploymentException: WELD-001409 Ambiguous dependencies for type [ProductService] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private wedvich.ProductController.productService]. Possible dependencies [[Session bean [class wedvich.ProductService with qualifiers [@Any @Default]; local interfaces are [ProductService], Session bean [class wedvich.ProductService with qualifiers [@Any @Default]; local interfaces are [ProductService]]]

任何后续请求都会产生以下异常:

javax.servlet.ServletException: Servlet.init() for servlet wedvich.ApplicationConfig threw exception

java.lang.IllegalStateException: The resource configuration is not modifiable in this context

为什么会这样?有没有什么明显的方法可以用我现在拥有的东西来解决它,或者我尝试过的项目组织/架构是否存在固有缺陷?

对于此类项目,我之前几乎只使用过 .NET 和 ASP.NET MVC,因此尝试使用我在帖子开头列出的约束条件的 Java 对我来说是新的。在涉足 Maven 或其他东西时,我很可能搞砸了一些事情,但我不知道该寻找什么。如果我能提供更多相关的信息,请告诉我,我会进行编辑。

【问题讨论】:

  • 您是否尝试过使用 @EJB 注释对 ProductService 字段进行注释?如果是,我建议您检查一切是否正确部署。
  • 当用@EJB 注释它时,我的例子有效。但是如果我尝试实际使用productService,我现在会得到一个 NullPointerException,所以看起来根本没有注入 EJB。关于如何实现这一点的任何提示?
  • 你确定ProductController是由容器管理的吗?也许您可以尝试使用@Statless 注释来对其进行注释,以确保它由容器管理。
  • 如果你希望它是一个 EJB,你可以用无状态来注解它,而这里不是这种情况,因为它是一个 JAX-RS 控制器。看看错误是如何来自 Weld 的?这意味着正在尝试注入,因此它绝对是“服务器管理的”。
  • 您是否将您的 ProductService 从一个包移动到另一个包并且没有清理干净?

标签: java maven jakarta-ee ejb jax-rs


【解决方案1】:

你应该注入接口而不是类本身!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多