cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Cannot deserialize JSON via JacksonJaxbJsonProvider (that works via Jackson's ObjectMapperm anyway)
Date Wed, 17 Jul 2013 16:22:17 GMT
Hi,
On 17/07/13 16:33, Francesco Chicchiriccò wrote:
> On 17/07/2013 17:07, Sergey Beryozkin wrote:
>> OK, thanks for the info. I'll have a look asap.
>> FYI, I thing this what I believe the original client code can be
>> simplified. You may have a much simpler injection code directly with
>> jaxrs:client, accept & content-type headers can also be set on
>> jaxrs:client, so you only should get either a proxy injected or
>> WebClient (set 'serviceClass' attribute to a full WebClient class name).
>>
>> At the moment I suspect that a client proxy may not be providing a
>> correct type info to Jackson given a somewhat complex interface
>> declaration, I'll check. Please try using WebClient directly in meantime
>
> Thanks for suggestion; this works as expected:
>
>          WebClient client = restClientFactory.createWebClient().
> path("http://localhost:9080/syncope/cxf/schemas/user/NORMAL/fullname").
>                  accept(MediaType.APPLICATION_JSON);
>          SchemaTO schema = client.get(SchemaTO.class);
>
> Looking forward to see how client code could be simplified (and
> working...).
>

Thanks for the update. I'm pretty sure I know what the problem is.

When we have a proxy, all it sees is

<T extends AbstractSchemaTO> T read(@PathParam("kind") AttributableType 
kind, @PathParam("type") SchemaType type,  @PathParam("name") String 
schemaName);

Now the problem here is that SchemaTO.class is not visible to proxy, so 
what it reports to Jackson is that it expects an instrance of 
AbstractSchemaTO.class back (which is all it can find from the signature).

I wonder if "T extends AbstractSchemaTO" needs to pushed up from all the 
methods to the interface declaration, and even after that is done, we 
probably need to add a new factory method, so that one can do

SchemaService<SchemaTO> service = JAXRSClientFactory.create(address, new 
GenericType<SchemaService<SchemaTO>>(){});
(using JAX-RS 2.0 GenericType)

So that when we do

proxy.read(...), the proxy is capable of passing the correct info to the 
providers,

So, it is an interesting enhancement to deal with :-) (won't make into 
2.7.6 though, Dan is busy with doing the release as we speak), but in 
meantime using WebClient will do

Thanks, Sergey

> Regards.
>
>> On 17/07/13 15:45, Francesco Chicchiriccò wrote:
>>> On 17/07/2013 16:39, Sergey Beryozkin wrote:
>>>> Hi Francesco,
>>>>
>>>> How do you use WebClient, let me know and I'll will check
>>>
>>> (restClientFactory is injected via Spring)
>>>
>>> restClientFactory.setServiceClass(SchemaService.class);
>>> final T serviceProxy = restClientFactory.create(SchemaService.class);
>>> WebClient.client(serviceProxy).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON);
>>>
>>>
>>>
>>> then
>>>
>>> serviceProxy.read(AttributableType.USER, SchemaType.NORMAL,
>>> "firstname"));
>>>
>>> this last statement throws the exception reported below.
>>>
>>> These are the last lines of the CXF client logging when executing the
>>> code above:
>>>
>>> 16:13:18.808 [main] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Chain
>>> org.apache.cxf.phase.PhaseInterceptorChain@555bc78f was created. Current
>>> flow:
>>>    receive [LoggingInInterceptor]
>>>    pre-protocol-frontend [ClientResponseFilterInterceptor]
>>>
>>> 16:13:18.808 [main] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking
>>> handleMessage on interceptor
>>> org.apache.cxf.interceptor.LoggingInInterceptor@2b95b0f5
>>> 16:13:18.810 [main] INFO  o.a.c.i.LoggingInInterceptor - Inbound Message
>>> ----------------------------
>>> ID: 1
>>> Response-Code: 200
>>> Encoding: UTF-8
>>> Content-Type: application/json;charset=UTF-8
>>> Headers: {content-type=[application/json;charset=UTF-8], Date=[Wed, 17
>>> Jul 2013 14:13:18 GMT], Server=[Apache-Coyote/1.1],
>>> transfer-encoding=[chunked]}
>>> Payload:
>>> {"name":"firstname","type":"String","mandatoryCondition":"false","enumerationValues":null,"enumerationKeys":null,"multivalue":false,"uniqueConstraint":false,"readonly":false,"conversionPattern":null,"validatorClass":null}
>>>
>>>
>>> --------------------------------------
>>> 16:13:18.810 [main] DEBUG o.a.cxf.phase.PhaseInterceptorChain - Invoking
>>> handleMessage on interceptor
>>> org.apache.cxf.jaxrs.client.spec.ClientResponseFilterInterceptor@7aaa977
>>> java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to
>>> org.apache.syncope.common.to.AbstractSchemaTO
>>>
>>>
>>> Thanks for your support!
>>> Regards.
>>>
>>>> On 17/07/13 15:20, Francesco Chicchiriccò wrote:
>>>>> Hi all,
>>>>> I have a quite silly question, probably due to my inexperience with
>>>>> CXF.
>>>>>
>>>>> Basically, in Syncope we have a set of CXF services producing both XML
>>>>> and JSON (via Jackson).
>>>>>
>>>>> At high level, I have troubles when reading JSON payload, via
>>>>> WebClient;
>>>>> the same input string (received as Payload), when given to a bare
>>>>> Jackson's ObjectMapper instance, works like a charm.
>>>>>
>>>>> More in detail, the CXF service configuration is the one at [1].
>>>>>
>>>>> When issuing, with header "Accept: application/json", an HTTP GET
>>>>> /syncope/cxf/schemas/user/NORMAL/fullname (e.g. read() as defined at
>>>>> [2]), it returns
>>>>>
>>>>> {
>>>>>    "name": "fullname",
>>>>>    "type": "String",
>>>>>    "mandatoryCondition": "true",
>>>>>    "enumerationValues": null,
>>>>>    "enumerationKeys": null,
>>>>>    "multivalue": false,
>>>>>    "uniqueConstraint": true,
>>>>>    "readonly": false,
>>>>>    "conversionPattern": null,
>>>>>    "validatorClass": null
>>>>> }
>>>>>
>>>>> which looks correct; in fact I am easily able to deserialize such
>>>>> input via
>>>>>
>>>>>          ObjectMapper mapper = new ObjectMapper();
>>>>>          SchemaTO actual = mapper.readValue(writer.toString(),
>>>>> SchemaTO.class);
>>>>>
>>>>> but when I try to use WebClient for accessing the same read() method
I
>>>>> get stuck with
>>>>>
>>>>> ClassCastException: java.util.LinkedHashMap cannot be cast to
>>>>> org.apache.syncope.common.to.AbstractSchemaTO
>>>>>
>>>>> which looks definitely like a Jackson exception.
>>>>>
>>>>> For additional reference, here is my client's Spring configuration [3]
>>>>> (see 'restClientFactory') and the AbstractSchemaTO [4] and SchemaTO
>>>>> classes [5].
>>>>>
>>>>> Nevertheless to say, switching to "Accept: application/xml" makes
>>>>> everything work again.
>>>>>
>>>>> I am using CXF 2.7.6-SNAPSHOT (this in order to be able to use Jackson
>>>>> 2.2.2).
>>>>>
>>>>> Any hint?
>>>>>
>>>>> Regards.
>>>>>
>>>>> [1]
>>>>> https://svn.apache.org/repos/asf/syncope/trunk/core/src/main/resources/restContext.xml
>>>>>
>>>>>
>>>>>
>>>>> [2]
>>>>> https://svn.apache.org/repos/asf/syncope/trunk/common/src/main/java/org/apache/syncope/common/services/SchemaService.java
>>>>>
>>>>>
>>>>>
>>>>> [3]
>>>>> https://github.com/ilgrosso/syncopeRestClient/blob/master/src/main/resources/applicationContext.xml
>>>>>
>>>>>
>>>>>
>>>>> [4]
>>>>> https://svn.apache.org/repos/asf/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AbstractSchemaTO.java
>>>>>
>>>>>
>>>>>
>>>>> [5]
>>>>> https://svn.apache.org/repos/asf/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java
>>>>>
>>>>>
>>>
>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Mime
View raw message