Инъекция CDI не работает в REST Resource в WAS Liberty с Джерси в качестве реализации JAX-RS - PullRequest
1 голос
/ 02 марта 2020

Я использую websphere liberty 19.0.0.8, и я хотел использовать Джерси вместо CXF по умолчанию для реализации jax-rs. Я удалил функцию jaxrs-2.1 с сервера xml и упаковал jar-файлы реализации в моем веб-приложении .war.

<featureManager>
    <feature>servlet-4.0</feature>
    <feature>jndi-1.0</feature>
    <feature>requestTiming-1.0</feature>
    <feature>monitor-1.0</feature>
    <feature>localConnector-1.0</feature>
    <feature>restConnector-2.0</feature>

<!-- Do not add enabled webProfile-8.0 because we want to disable default 
    REST implementation (Apache-CXF) provided by Liberty. We want to use Jersey 
    as our REST implementation because it better support multi-part streaming, -->
    <!-- <feature>webProfile-8.0</feature> -->
    <feature>jsp-2.3</feature>
    <feature>cdi-2.0</feature>
    <feature>managedBeans-1.0</feature>
    <feature>jdbc-4.2</feature>
    <!-- <feature>jaxrs-2.1</feature> -->
</featureManager>

Сборка Gradle, включая реализацию джерси

//JxRS Jersey implementation    
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.25.1'       
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.25.1'
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-multipart', version: '2.25.1'
compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-json-provider', version: '2.9.0'

ResourceConfig расширенного джерси для настройки моего RestApplication

@ApplicationPath("/")
public class RestApplicationConfig extends ResourceConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(RestApplicationConfig.class);

    public RestApplicationConfig() {
        super();
        configureResourcesAndFeatures();
    }

    private void configureResourcesAndFeatures() {
        packages(RestApplicationConfig.class.getPackage().getName());
        register(MultiPartFeature.class);
    }
}

Со всей этой настройкой мой остальные API работают, и я возможность использовать несколько связанных классов Джерси в моем коде.

Теперь проблема с CDI. В моем классе ресурсов я могу внедрить управляемый ресурс / классы CDI, например

@ApplicationScoped
@Path("/ping")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PingResource {

    private static final Logger LOGGER = LoggerFactory.getLogger(PingResource.class);

    @Resource(lookup = "jndi_dpa_iss_rest_url")
    private String issRestBaseUrlInResource;

    @Inject
    private DocumentService documentService;
}

В вышеприведенном классе @Resource и @Inject не могут разрешить ресурс JNDI и управляемый компонент. Как только я включаю функцию jaxrs-2.1 на сервере. xml Внедрение CDI работает, но затем я теряю джерси, он использует CXF.

DocumentService, и его класс реализации определяется следующим образом. Все находится в одном пакете с классом RestApplicationConfig или его подпакетами.

@ApplicationScoped
@Transactional(value = Transactional.TxType.NOT_SUPPORTED)
public class DocumentServiceImpl implements DocumentService {
    // some code here
}

Что мне нужно для использования CDI в моих классах ресурсов отдыха?

1 Ответ

1 голос
/ 06 марта 2020

Поскольку в настоящее время нет расширения джерси для CDI 2.0, мне пришлось искать обходной путь. Обходной путь - вручную запросить контейнер CDI для интересующего нас типа компонента. Таким образом, мы вручную внедряем компонент CDI в наш класс ресурсов, но внедренный компонент является экземпляром управляемого компонента, поэтому CDI позаботился о том, чтобы удовлетворить все его зависимости.

Это мы делаем ручную инъекцию только в слое Resource, но CDI должен нормально работать для слоя вниз.

Рабочий код.

@ApplicationScoped
@Path("/ping")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class PingResource {

    private DocumentService documentService = CDI.current().select(DocumentService.class).get();

}

По сути вместо @Inject, запрос вручную Контейнер CDI.

...