简体   繁体   中英

CXF/RestTemplate deserialization issue

I have several PJO's that represent a response object from an Apache CXF web service (2.7.2). All my root element classes are annotated with @XmlRootElement .

Here are the POJO classes:

@XmlRootElement(name="SearchResponse")
public class SearchResponse extends Response {
    private Listing[] listings;
    private SearchSummary summary;
...
}

and

@XmlRootElement(name="SearchResponseRestricted")
public class SearchResponseRestricted extends Response {

    private ListingRestricted[] listings;
    private SearchSummary summary;
...
}

Using @AutoWired public RestTemplate getRESTClient(); , I can succesfully call the method that returns the SearchResponseRestricted result, but not the SearchResponse .

SearchResponseRestricted response = getRESTClient().postForObject(getUrlForJSON()+"/findRestricted", generateJSONRequest(request), SearchResponseRestricted.class); <-- Success

The above succeeds, whereas the following fails to deserialize:

SearchResponse response = getRESTClient().postForObject(getUrlForJSON()+"/find", generateJSONRequest(request), SearchResponse.class); <-- Fails

generateJSONRequest for brevity:

public HttpEntity<Object> generateJSONRequest(Object object) {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    return new HttpEntity<Object>(object, headers);
}

It's worth noting, BOTH method calls return JSON back from the Web Service and the JSON data looks to be representative of the Classes that should be deserialized

When the method that fails to deserialize is called, I get the following exception:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.pkg.ws.pub.SearchResponse] and content type [application/json] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:108) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:535) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:489) at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:318) at com.pkg.ws.service.SearchServiceWSTest.testFind(SearchServiceWSTest.java:362) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at junit.framework.TestCase.runTest(TestCase.java:176) at junit.framework.TestCase.runBare(TestCase.java:141) at junit.framework.TestResult$1.protect(TestResult.java:122) at junit.framework.TestResult.runProtected(TestResult.java:142) at junit.framework.TestResult.run(TestResult.java:125) at junit.framework.TestCase.run(TestCase.java:129) at junit.framework.TestSuite.runTest(TestSuite.java:255) at junit.framework.TestSuite.run(TestSuite.java:250) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Can anyone point me in the right direction or suggest what I may be overlooking?

So I figured out what was wrong. On the failing class, the Listing object had a field in it that subclassed an abstract class ( Region )

I ended up simply having to add a few extra annotations listing the known subclasses:

@XmlSeeAlso({RegionAlt.class,RegionGeneric.class,RegionLBA.class,RegionGeom.class,RegionLoc.class,RegionMulti.class,RegionRad.class,RegionStyle.class,RegionPC.class,RegionHi.class,RegionIntersec.class})
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class Region extends .... implements... {
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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