我使用CXF和Spring进行了全功能的JAXRS REST API设置。但是,我似乎无法指示我的代理服务使用我的JAXB设置来反序列化我的JODA时间参数。
我收到了异常消息:Parameter Class org.joda.time.DateTime has no constructor with single String parameter, static valueOf(String) or fromString(String) methods
我已设置ParamConverterProvider
来处理转换,但这似乎没有被提取(调试时它不会调用我的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
}