Hi Sadhana

Hi Sergey,

Thank you very much. I think that will certainly help. I will give it a try.
One more question I have is is JsonProvider able to read json arrays? If I
have something like this:
[{"a","b"}, {"c", "d"}] will it be able to unmarshal to a java class that
declares a list inside it (of course after I add the wrapper element)?

Not in 2.2.4 but I hopw it will actually be possible on the trunk. When unmarshalling such a sequence into a JAXB bean, there're two elements which are missing. For ex, "AllCredentials" (root) and the collection root, say 'list', assuming you hae something like

@XmllRootElement
public class AllCredentials {
 List<Credentials> list;
}

When using JSONProvider (which is JAXB-based), it is not possible to specify multiple wrapper names, say, "AllCredentials" and "list", such that "AllCredentials" actually wraps "list", but with the feature which I committed yesterday evening, it is (should be) possible to achieve it

So to deserialize the above sequence, you'd need to add a wrapperName "list" (which is actually appended to the raw sequence), and also set an 'inAppendElements' map property :

Collections.singletonMap("list", "AllCredentials")

key is the name of the element which the value has to be appended before (in this exampel : add 
"AllCredentials" before "list")

This should do it. Note that this feature is not documented yet and it is 
availbale only on the trunk/2.2.5-SNAPSHOT.

By the way, regarding your earlier issue, the info at

[1]
http://cxf.apache.org/docs/jax-rs.html#JAX-RS-WrappingandUnwrappingJSONs
equences


is incomplete, "supportUnwrapped" boolean property has to be set too...

I'll be working on documenting all the new updates in time for 2.2.5 and will 
fix the docs

thanks, Sergey


Thanks again,
Sadhana

P.S. Please ignore my dup message as I didn't see my earlier message being
posted so resent it.


On 11/8/09 9:57 AM, "Sergey Beryozkin" <[email protected]> wrote:

Hi

It is a sequence without a root element, so you need to apply one extra
bit of configuration to the JSONProvider instance [1], wrapperName="",
given that you set XMlRootElement name to "". Perhaps it would make
sense to use @XmlRootElement and wrapperName="Credentials" ? If you have
not only Credentials but other classes to deal with then you may want to
use a wrapperMap property instead.

Updating the JSONProvider to handle custom consume types is a better
solution, but in case you'll need to use inInterceptors then you can
change the Content-Type like this

message.set(Message.CONTENT_TYPE, "application/json");

Hope it helps, Sergey

[1]
http://cxf.apache.org/docs/jax-rs.html#JAX-RS-WrappingandUnwrappingJSONs
equences

-----Original Message-----
From: Sadhana Jain [mailto:[email protected]]
Sent: 07 November 2009 08:18
To: [email protected]
Subject: Re: Is it possible to parse json response using JAXRS
WebClient?

Hi Sergey,
Thanks very much again for your quick reply. I was able to get the
correct
content-type set by creating the JsonProvider in the code and setting
the
media types and using WebClient's create method to register the
provider.

However, I am still not able to get the json parsed and stored in the
Credentials bean correctly. I get this error during parsing (which
unmarshaller should the JosnProvider use to unmarshall json?):

Nov 7, 2009 12:02:40 AM
org.apache.cxf.jaxrs.provider.AbstractJAXBProvider
handleJAXBException
WARNING: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: unexpected element (uri:"",
local:"id").
Expected elements are <{}>]
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamEx
cept
ion(UnmarshallerImpl.java:425)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unm
arsh
allerImpl.java:362)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unma
rsha
llerImpl.java:332)
    at
org.apache.cxf.jaxrs.provider.JSONProvider.readFrom(JSONProvider.java:15
6)
    at
org.apache.cxf.jaxrs.client.AbstractClient.readBody(AbstractClient.java:
401)
    at
org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:544)
    at
org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java
:536
)
    at
org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:510)
    at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:286)
    at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:314)
    at
gwy.flixster.FlixsterAPITest.getCredentialsTest(FlixsterAPITest.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
a:39
)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
Impl
.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
98)
    at
org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(Met
hodR
oadie.java:87)
    at
org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4Clas
sRun
ner.java:88)
    at
org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunne
r.ja
va:51)
    at
org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.jav
a:44
)
    at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:2
7)
    at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at
org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:
42)
    at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4Tes
tRef
erence.java:46)
    at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.ja
va:3
8)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRu
nner.java:467)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
stRu
nner.java:683)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRun
ner.
java:390)
    at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRu
nner
.java:197)
Caused by: javax.xml.bind.UnmarshalException: unexpected element
(uri:"",
local:"id"). Expected elements are <{}>,<{}tokens.json>
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEven
t(Un
marshallingContext.java:642)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:
254)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:
249)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildEle
ment
(Loader.java:116)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRoo
tLoa
der.childElement(UnmarshallingContext.java:1049)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElem
ent(
UnmarshallingContext.java:478)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startEleme
nt(U
nmarshallingContext.java:459)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElemen
t(In
terningXmlVisitor.java:71)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStart
Elem
ent(StAXStreamConnector.java:242)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAX
Stre
amConnector.java:176)
    at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unm
arsh
allerImpl.java:360)
    ... 31 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element
(uri:"",
local:"id"). Expected elements are <{}>]
    ... 42 more

The json response from the service looks like this:
{
    "id": 157373130,
    "token":"xxxx......."
........
}

In the Credentails class I have:
@XmlRootElement(name="")
public class Credentials
{
  private String id;
  private String token;

....

Getter/setters defined.
}


Any idea why I am getting this exception? Which reader does actually do
the
json unmarshalling?

Thanks much,
Sadhana

P.S. Thanks for the info on Spring configuration - I tried it but am
running
into issues. I will try later after it is working without spring
configuration. I tried InInterceptor to change the content type but
didn't
know how I will set it in the Message. I didn't see any methods to set
the
values. Can you please give an example?


On 11/6/09 3:26 PM, "Sergey Beryozkin" <[email protected]> wrote:

Hi

You can update the incoming Content-Type in a couple of ways :
1. Configure JSONProvider to accept text/javascript and
application/json
(set consumeTypes on it).
When registering JSONProvider from Spring you can do the way it's done
here :

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resour
ces/jaxrs/WEB-INF/beans.xml

See the 'jsonProvider' bean.

Or you can configure a JSONProvider from the code and register it
using
one of the WebClient.create() methods

2. Register a custom CXF input interceptor (as shown below for
LoggingInInterceptor) and set a Message.ContentType property on the
message to application/json


Is there a way to specify configuration in Spring? Also how does
jaxrs:client configuration in Spring work for WebClient?

jaxrs:client is a proxy based client created from spring and it is
meant
to be injected into a client code. But you can also create and
configure
a WebClient from Spring if needed but it will also have to be injected
into the code - is it what you'd like to do ?
For ex, if a jaxrs:client or WebClient bean created from spring has an
id 'client' then you can have a field (of type WebClient for ex)
annotated with @Resource("client") and Spring will inject this
bean....


If I want to configure my own MessageBody Json reader for processing
the
json response, how would I do that?

Please see above : either from code or from Spring

Cheers, Sergey


-----Original Message-----
From: Sadhana Jain [mailto:[email protected]]
Sent: 06 November 2009 18:13
To: [email protected]
Subject: Re: Is it possible to parse json response using JAXRS
WebClient?

Hi Sergey,

Thank you so much for your quick responses and elaborate replies.


On 11/6/09 5:31 AM, "Sergey Beryozkin" <[email protected]> wrote:

Hi Sadhana

Hi Sergey,

Here is what I am doing:
WebClient wc =
WebClient.create("http://xxx.com/api/v1/tokens.json";);
   wc.query("login", "jessicamontgomery");
   wc.query("password", "password");
   Credentials c =
wc.accept("application/json").get(Credentials.class);

Credentials class is a pojo that contains all the getter/setters for
all
keys in the json response I am getting from the service.

Is it a JAXB bean ?
Yes, I did put the XmlRootElement annotation for the class thought the
element name is null as I don't have a corresponding element in the
json
response.


The Error I get is:
Nov 6, 2009 2:00:58 AM org.apache.cxf.jaxrs.client.AbstractClient
reportNoMessageHandler
SEVERE: .No message body reader found for class : class
gwy.flixster.pojo.Credentials, ContentType : {1}.


If Credentials  is not a JAXB bean then JSONProvider will return
false
in
isReadable()
Another thing to check what ContentType the target service sets on
the
response. You can do it with a tcp trace utilty (for ex,
assuming the target service is listening on "http://xxx.com:8080";
then
you
update the client code to send a request to
"http://xxx.com:8081"; and configure a tcptrace to redirect to
"http://xxx.com:8081";).
Thanks for the tip. I did find that Content-Type returned was
text/javascript instead of application/json. I tried text/javascript
as
accept header but still get the same error.


Another option is to configure a logging feature or logging in
interceptor :

WebClient.getConfig(client).getInInterceptors().add(new
LoggingInInterceptor())

Is there a way to specify configuration in Spring? Also how does
jaxrs:client configuration in Spring work for WebClient?


Do I need to define jsonprovider whe creating the webclient?

No, unless you'd like to configure the JSONProvider somehow. For
example, if
Credentials is not annotated with say @XmlRootElement
then you can configure JSONProvider with a property
'unmarshallAsJaxbElement'
with a value 'true'.

If I want to configure my own MessageBody Json reader for processing
the
json response, how would I do that?

Thanks a lot....again!
Sadhana
thanks, Sergey


Thanks,
Sadhana

On 11/6/09 1:37 AM, "Sergey Beryozkin" <[email protected]>
wrote:

Hi,


Hi,

I am using the JAXRS WebClient API and get a json response from a
rest
service. Does CXF support reading of the json using a message body
reader
that I can attach to the WebClient? Are there any examples of the
usage of
WebClient showing processing of the response?

It should work out of the box....What issues you're seeing in
reading JSON ?
Can you please post a sample
sequence ?

thanks, Sergey


Thanks very much for any help.
Sadhana







Reply via email to