CXF-клиентский прокси-сервер не использует мой зарегистрированный ParamConverterProvider

#java #spring #cxf #cxfrs #cxf-client

#java #весна #cxf #cxfrs #cxf-client

Вопрос:

У меня есть полностью функциональная настройка JAXRS REST API с использованием CXF и Spring. Однако, похоже, я не могу поручить своим прокси-сервисам использовать настройку use my JAXB для де-сериализации моих временных параметров JODA.

Я получаю сообщение об исключении: Parameter Class org.joda.time.DateTime has no constructor with single String parameter, static valueOf(String) or fromString(String) methods

Я настроил a ParamConverterProvider для обработки преобразования, но, похоже, это не улавливается (при отладке он не вызывает my ParamConverterProviderImpl ). Как я могу сказать cxf использовать его и для моих прокси.

Я использую CXF 3.0.0, и моя настройка выглядит следующим образом:

У меня есть служба JAXRS

 @Path("/entries")
@Produces({"application/json", "application/xml"})
@Consumes({"application/json", "application/xml", "text/xml"})
public interface RSEntryService {

    @GET
    @Path("/summed")
    public ApiEntries getSummedEntries(@QueryParam("") ApiDateRangeFilter filter) throws Exception;
}
 

С реализацией

 public class RSEntryServiceImpl implements RSEntryService {
    @Override
    public ApiEntries getSummedEntries(ApiDateRangeFilter filter) throws Exception {
        ... do stuff ...
}
 

Где ApiDateRangeFilter выглядит следующим образом

 @XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "daterangefilter")
public class ApiDateRangeFilter {

@XmlJavaTypeAdapter(value=DateAdapter.class)
private DateTime start;

@XmlJavaTypeAdapter(value=DateAdapter.class)
private DateTime end;

    ... getters and setters ...
}
 

сервисы подключены следующим образом:

 <jaxrs:server id="rsAPIServices"
    address="${joostschouten.businessadmin.api.rs.server.address}">
    <jaxrs:serviceBeans>
        <ref bean="com.joostschouten.businessadmin.api.rs.RSEntryService" />
        <!-- Swagger API Listing resource -->
        <ref bean="swaggerResourceJSON" />
    </jaxrs:serviceBeans>
    <jaxrs:extensionMappings>
        <entry key="xml" value="application/xml" />
        <entry key="json" value="application/json" />
    </jaxrs:extensionMappings>
    <jaxrs:providers>
        <bean class="com.joostschouten.businessadmin.api.rs.parameterhandlers.ParamConverterProviderImpl" />
        <ref bean="jaxrsJsonProvider"/>
        <!-- <ref bean="jaxrsJsonProvider"/> -->
        <bean class="com.joostschouten.businessadmin.api.rs.exception.RSExceptionMapper" />
        <!-- required for writing swagger classes -->
        <ref bean="resourceWriter" />
        <ref bean="apiWriter" />
    </jaxrs:providers>
    <jaxrs:inInterceptors>
        <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor" />
        <ref bean="depthInterceptor" />
    </jaxrs:inInterceptors>
    <jaxrs:outInterceptors>
        <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor" />
        <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor" />
    </jaxrs:outInterceptors>
</jaxrs:server>
<bean id="jaxrsJsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
    <property name="dropRootElement" value="${joostschouten.businessadmin.api.rs.dropJsonRootElement}" />
    <property name="supportUnwrapped" value="${joostschouten.businessadmin.api.rs.supportUnwrappedJson}" />
</bean>
 

И я настроил прокси для использования в своих тестах, который настроен

 <jaxrs-client:client address="${joostschouten.businessadmin.api.rs.server.address}"
    id="com.joostschouten.businessadmin.api.rs.RSEntryService.proxy"
    serviceClass="com.joostschouten.businessadmin.api.rs.RSEntryService">
    <jaxrs-client:providers>
        <bean class="com.joostschouten.businessadmin.api.rs.parameterhandlers.ParamConverterProviderImpl" />
    </jaxrs-client:providers>
</jaxrs-client:client>
 

ParamConverterProvider

 @Provider
public class ParamConverterProviderImpl implements ParamConverterProvider {

    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
            if(rawType.equals(LocalDate.class)) {
                    return (ParamConverter<T>) new LocalDateHandler();
            }
            else if (rawType.equals(Date.class)) {          
                    return (ParamConverter<T>) new DateHandler();
            }
            return null;
    }

}
 

В моем тесте, где я использую прокси, у меня есть:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/spring/test-joostschouten-businessadmin-beans.xml"})
public class RSEntryServiceImplIntegrationTest {

    @Autowired
    @Qualifier("com.joostschouten.businessadmin.api.rs.RSTimeEntryService.proxy")
    protected RSEntryService proxy;

    @Test
    public void testGetSummedEntries() throws Exception {
        ApiDateRangeFilter dateRangeFilter = new ApiDateRangeFilter();
        dateRangeFilter.setStart(new DateTime().minusDays(20));
        dateRangeFilter.setEnd(new DateTime().plusDays(10));

        ApiEntries summedEntries = proxy.getSummedTimeEntries(dateRangeFilter);//exception on this line
    }
 

Комментарии:

1. Побочное замечание — если вы настроите CXF на использование Jackson для обработки JSON / XML, вы можете включить модуль joda Джексона, который обрабатывает классы времени joda.

2. @AlexeyGavrilov Спасибо, приятно знать! Хотя для других типов данных я все равно хотел бы сделать эту работу.

3. Когда-нибудь это работало? На данный момент у меня точно такая же проблема с аналогичной настройкой swagger / cxf.

4. К сожалению, у меня это не сработало, и в конце концов я изменил свой ApiDateRangeFilter на использование String для хранения дат и выполнения де-серилизации в моем собственном коде. Через несколько дней мне просто нужно было, чтобы он работал;-) Извините, у меня нет лучшего ответа. Удачи!

5. Этот код работает для меня с CXF 3.0.3 и создан вручную JAXRSServerFactoryBean , с ParamConverterProviderImpl добавлением using factory.setProviders(…) .