繁体   English   中英

使用JAX-RS和Glassfish进行CDI和资源注入

[英]CDI and Resource Injection with JAX-RS and Glassfish

我目前正在开发一个JAX-RS Servlet,然后我想在Glassfish 4.1 Server中部署(因此JAX-RS运行时是Jersey 2.x)。

我没有尝试使用Spring进行配置和DI工作,而是想尝试Java EE的方式。 但是,CDI和我在Glassfish服务器中配置的数据源的注入都不起作用。 但首先,这里是关于servlet的相关内容。

依赖关系(在父pom中用版本和范围声明 - 这不是你在这里看到的那个):

<dependencies>
    <!-- Java EE API -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
    </dependency>

    <!-- Jersey CDI support -->
    <dependency>
        <groupId>org.glassfish.jersey.ext.cdi</groupId>
        <artifactId>jersey-cdi1x</artifactId>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.ext.cdi</groupId>
        <artifactId>jersey-cdi1x-ban-custom-hk2-binding</artifactId>
    </dependency>

    <!-- Logging dependencies -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
    </dependency>
</dependencies>

web.xml中:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1">

<servlet>
    <servlet-name>Backend</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

    <!-- Disable Moxy JSON -->
    <init-param>
        <param-name>jersey.config.disableMoxyJson</param-name>
        <param-value>true</param-value>
    </init-param>

    <!-- Register resource classes -->
    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>org.test.Service</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>Backend</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>

beans.xml中:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
   version="1.1" bean-discovery-mode="all">
</beans>

Service.java:

@Path("/")
@RequestScoped
public class Service {

    @Inject
    private DataProvider dataProvider;

    @Path("test")
    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public Response test(){
        return Response.ok(dataProvider.getArticles()).build();
    }

}

SQLDataProvider.java:

@Default
@ApplicationScoped
@Singleton
@Path("singleton-bean")
public class SQLDataProvider implements DataProvider {

    @Resource(name = "jdbc/db_1")
    private DataSource dataSource;

    private SQLQueryFactory factory;

    @Override
    public List<Article> getArticles() {
        if(factory == null){
            factory = new SQLQueryFactory(new Configuration(new MySQLTemplates()), dataSource);
        }

        QArtikel artikel = QArtikel.artikel;
        List<String> names = factory.select(artikel.artikeltyp).from(artikel).fetch();

        return names.stream().map(Article::new).collect(Collectors.toList());
    }
}

如果我在Glassfish服务器中部署此servlet并执行请求,则会引发以下异常:

javax.servlet.ServletException: A MultiException has 3 exceptions.  They are:
    1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=DataProvider,parent=SkiBazaarService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,158365417)
    2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of org.skiclub.service.SkiBazaarService errors were found
    3. java.lang.IllegalStateException: Unable to perform operation: resolve on org.skiclub.service.SkiBazaarService

正如你所看到的,我已经在这篇文章中尝试了用户G. Demecki的解决方案,将两个Jersey依赖项包含在我的servlet中 - 但没有成功。 我也尝试过Oracle的解决方案 ,该帖子已在本文的某处发布 但这对我来说也不起作用。

我还看到了一个解决方案,在这个解决方案中,您可以在本文中为HK2运行时指定从类型到实例的绑定。 我承认我没有尝试过,因为我认为必须以编程方式注册要注入的实例,这绝对是DI背后的想法。

但是还有另一个问题。 如果我将Service类中DataProvider的声明修改为以下内容

private DataProvider dataProvider = new SQLDataProvider();

CDI的问题消失但是NPE被抛出,因为我试图从JNDI获取的DataSource没有被注入到SQLDataProvider的实例中。 因此,似乎Java EE的资源注入在JAX-RS容器中也不起作用。 对于这个问题,我在研究期间没有找到任何可能的解决方案。

我希望有人可以告诉我我需要在配置中进行哪些更改才能使CDI和资源注入与JAX-RS协同工作,因为目前这对我来说似乎是不可能的。

亲切的问候Pascal

看到这个问题:

查找工作时,Recource注入不适用于glassfish 4

尝试在您的Resource查找不同的属性,如上面的问题所示的mappedName

 @Resource(mappedName = "jdbc/db_1")
 private DataSource dataSource;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM