Hi Francesco,

I am not 100% sure that is a solution for your case, but I have used Jackson 
specific annotation in AbstractSchemaTO:
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY, property="class").

Annotation is currently deactivated, because it causes conflicts with Syncope 
Spring MVC Rest implementation.
The annotation forces client to send concrete class name in JSON 
representation, as a result service has more information to construct concrete 
class.
As I can remember, I have tested this code for JSON using CXF JAX-RS client and 
service.

Could you try to activate it and retest?

Regards,
Andrei.

> -----Original Message-----
> From: Francesco Chicchiriccò [mailto:[email protected]]
> Sent: Donnerstag, 18. Juli 2013 09:26
> To: [email protected]
> Subject: Re: Cannot deserialize JSON via JacksonJaxbJsonProvider (that
> works via Jackson's ObjectMapperm anyway)
>
> On 17/07/2013 18:22, Sergey Beryozkin wrote:
> > 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.
>
> Good :-)
>
> > 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),
>
> Understand: are you going to open an issue for this?
>
> > but in meantime using WebClient will do
>
> As a proof-of-concept, for sure; however, we need to keep the same CXF
> code for both XML and JSON, hence we will be waiting for the enhancement
> above.
>
> Thanks again for your support.
> 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).acc
> >>>> ept(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","e
> >>>> numerationValues":null,"enumerationKeys":null,"multivalue":false,"u
> >>>> niqueConstraint":false,"readonly":false,"conversionPattern":null,"v
> >>>> alidatorClass":null}
> >>>>
> >>>>
> >>>>
> >>>> --------------------------------------
> >>>> 16:13:18.810 [main] DEBUG o.a.cxf.phase.PhaseInterceptorChain -
> >>>> Invoking handleMessage on interceptor
> >>>> org.apache.cxf.jaxrs.client.spec.ClientResponseFilterInterceptor@7a
> >>>> aa977
> >>>>
> >>>> 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/o
> rg/apache/syncope/common/services/SchemaService.java
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> [3]
> >>>>>>
> https://github.com/ilgrosso/syncopeRestClient/blob/master/src/main/resou
> rces/applicationContext.xml
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> [4]
> >>>>>>
> https://svn.apache.org/repos/asf/syncope/trunk/common/src/main/java/o
> rg/apache/syncope/common/to/AbstractSchemaTO.java
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> [5]
> >>>>>>
> https://svn.apache.org/repos/asf/syncope/trunk/common/src/main/java/o
> rg/apache/syncope/common/to/SchemaTO.java
> >>>>>>
> >
>
> --
> Francesco Chicchiriccò
>
> ASF Member, Apache Syncope PMC chair, Apache Cocoon PMC Member
> http://people.apache.org/~ilgrosso/

Reply via email to