Quantcast

How to convert response input stream to java object

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

How to convert response input stream to java object

dan0
Hi all,

Up until now I've had the web client return the desired java object rather then
a Response object, i.e. Object target =
client.type("application/json").accept("application/json").get(Target.class)

But now I want to check the response and then get the entity/message body, but
I'm stuck on how to convert the response input stream -- Response.getEntity() --
into the desired java object.

I'm using all default settings, all the DTO classes use jaxb annotations
(@XmlRootElement), and the message body is in json format. Does anyone know how
to do the conversion/unmarshalling? Can anyone point me to some examples?


Thanks.

-Dan



     
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Glen Mazza (Talend)
I think ResponseReader, recently introduced in CXF 2.3.1, is your friend.

If you go to the Talend Service Factory (CXF wrap) Examples[1], under
examples/jaxrs-advanced/client/..../RESTClient.java, method
useSimpleProxy() has it.

Glen

[1] http://www.talend.com/resources/documentation.php#SF

On 20.01.2011 22:11, Dan King wrote:

> Hi all,
>
> Up until now I've had the web client return the desired java object rather then
> a Response object, i.e. Object target =
> client.type("application/json").accept("application/json").get(Target.class)
>
> But now I want to check the response and then get the entity/message body, but
> I'm stuck on how to convert the response input stream -- Response.getEntity() --
> into the desired java object.
>
> I'm using all default settings, all the DTO classes use jaxb annotations
> (@XmlRootElement), and the message body is in json format. Does anyone know how
> to do the conversion/unmarshalling? Can anyone point me to some examples?
>
>
> Thanks.
>
> -Dan
>
>
>
>


--
Glen Mazza
Software Engineer, Talend (http://www.talend.com)
blog: http://www.jroller.com/gmazza


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Sergey Beryozkin
ResponseReader is a custom MessageBodyReader<Response> handler which is
registered on the client side, it allows to do a safe type casting, such as

Response response = webClient.get();
Book book = (Book)Response.getEntity();

It's possibe to write your own custom Response reader with any CXF version
supporting the client api, but using the ResponseReader makes it simpler...

Please check the demo Glen linked to.

Sergey

On Fri, Jan 21, 2011 at 4:08 AM, Glen Mazza <[hidden email]> wrote:

> I think ResponseReader, recently introduced in CXF 2.3.1, is your friend.
>
> If you go to the Talend Service Factory (CXF wrap) Examples[1], under
> examples/jaxrs-advanced/client/..../RESTClient.java, method useSimpleProxy()
> has it.
>
> Glen
>
> [1] http://www.talend.com/resources/documentation.php#SF
>
>
> On 20.01.2011 22:11, Dan King wrote:
>
>> Hi all,
>>
>> Up until now I've had the web client return the desired java object rather
>> then
>> a Response object, i.e. Object target =
>>
>> client.type("application/json").accept("application/json").get(Target.class)
>>
>> But now I want to check the response and then get the entity/message body,
>> but
>> I'm stuck on how to convert the response input stream --
>> Response.getEntity() --
>> into the desired java object.
>>
>> I'm using all default settings, all the DTO classes use jaxb annotations
>> (@XmlRootElement), and the message body is in json format. Does anyone
>> know how
>> to do the conversion/unmarshalling? Can anyone point me to some examples?
>>
>>
>> Thanks.
>>
>> -Dan
>>
>>
>>
>>
>>
>
> --
> Glen Mazza
> Software Engineer, Talend (http://www.talend.com)
> blog: http://www.jroller.com/gmazza
>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

dan0
Thanks for the help; however, I do have a few follow-up questions:

1. Can "ResponseReader" be used with "WebClient" objects or is its use limited
to client proxies only? i.e.


ResponseReader reader = new ResponseReader();
reader.setEntityClass(Book.class);

JAXRSClientFactory.create("http://localhost:8080/books", BookStore.class,
Collections.singletonList(reader));2. Where can I find examples of custom
message body reader/writer implementation examples? I've searched everywhere and
found nothing that helps in understanding how to implement a custom one.

3. I checked the example Glenn suggested, however that example does NOT use
"ResponseReader". The method "useSimpleProxy" in "RESTClient.java", creates a
client proxy from which it retrieves a collection of person objects; it never
deals with a "Response" object. Did I miss something in the example?

Thanks.

-Dan

----- Original Message ----

> From: Sergey Beryozkin <[hidden email]>
> To: [hidden email]
> Sent: Fri, January 21, 2011 6:37:54 AM
> Subject: Re: How to convert response input stream to java object
>
> ResponseReader is a custom MessageBodyReader<Response> handler which  is
> registered on the client side, it allows to do a safe type casting, such  as
>
> Response response = webClient.get();
> Book book =  (Book)Response.getEntity();
>
> It's possibe to write your own custom  Response reader with any CXF version
> supporting the client api, but using the  ResponseReader makes it simpler...
>
> Please check the demo Glen linked  to.
>
> Sergey
>
> On Fri, Jan 21, 2011 at 4:08 AM, Glen Mazza <[hidden email]> wrote:
>
> > I  think ResponseReader, recently introduced in CXF 2.3.1, is your  friend.
> >
> > If you go to the Talend Service Factory (CXF wrap)  Examples[1], under
> > examples/jaxrs-advanced/client/..../RESTClient.java,  method
useSimpleProxy()

> > has it.
> >
> > Glen
> >
> > [1]  http://www.talend.com/resources/documentation.php#SF
> >
> >
> >  --
> > Glen Mazza
> > Software Engineer, Talend  (http://www.talend.com)
> > blog:  http://www.jroller.com/gmazza
> >
> >
> >
>


     
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Sergey Beryozkin
Hi

When creating web clients, you can do
WebClient.create("http://localhost:8080/books",
Collections.singletonList(reader));

If you have different types returned by the same WebClient, then just reset
the entity class on the reader before
making a call....

Cheers, Sergey

On Fri, Jan 21, 2011 at 4:34 PM, Dan King <[hidden email]> wrote:

> Thanks for the help; however, I do have a few follow-up questions:
>
> 1. Can "ResponseReader" be used with "WebClient" objects or is its use
> limited
> to client proxies only? i.e.
>
>
> ResponseReader reader = new ResponseReader();
> reader.setEntityClass(Book.class);
>
> JAXRSClientFactory.create("http://localhost:8080/books", BookStore.class,
> Collections.singletonList(reader));2. Where can I find examples of custom
> message body reader/writer implementation examples? I've searched
> everywhere and
> found nothing that helps in understanding how to implement a custom one.
>
> 3. I checked the example Glenn suggested, however that example does NOT use
> "ResponseReader". The method "useSimpleProxy" in "RESTClient.java", creates
> a
> client proxy from which it retrieves a collection of person objects; it
> never
> deals with a "Response" object. Did I miss something in the example?
>
> Thanks.
>
> -Dan
>
> ----- Original Message ----
>
> > From: Sergey Beryozkin <[hidden email]>
> > To: [hidden email]
> > Sent: Fri, January 21, 2011 6:37:54 AM
> > Subject: Re: How to convert response input stream to java object
> >
> > ResponseReader is a custom MessageBodyReader<Response> handler which  is
> > registered on the client side, it allows to do a safe type casting, such
>  as
> >
> > Response response = webClient.get();
> > Book book =  (Book)Response.getEntity();
> >
> > It's possibe to write your own custom  Response reader with any CXF
> version
> > supporting the client api, but using the  ResponseReader makes it
> simpler...
> >
> > Please check the demo Glen linked  to.
> >
> > Sergey
> >
> > On Fri, Jan 21, 2011 at 4:08 AM, Glen Mazza <[hidden email]> wrote:
> >
> > > I  think ResponseReader, recently introduced in CXF 2.3.1, is your
>  friend.
> > >
> > > If you go to the Talend Service Factory (CXF wrap)  Examples[1], under
> > > examples/jaxrs-advanced/client/..../RESTClient.java,  method
> useSimpleProxy()
> > > has it.
> > >
> > > Glen
> > >
> > > [1]  http://www.talend.com/resources/documentation.php#SF
> > >
> > >
> > >  --
> > > Glen Mazza
> > > Software Engineer, Talend  (http://www.talend.com)
> > > blog:  http://www.jroller.com/gmazza
> > >
> > >
> > >
> >
>
>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Glen Mazza (Talend)

> On Fri, Jan 21, 2011 at 4:34 PM, Dan King<[hidden email]>  wrote:
>
>> 2. Where can I find examples of custom
>> message body reader/writer implementation examples? I've searched
>> everywhere and
>> found nothing that helps in understanding how to implement a custom one.

If you need to go that route, Example 6-02 of the JAX-RS book
examples[1] has a rather complex MessageBodyReader/Writer example.  Note
this example had uncovered a bug that was quickly fixed in CXF 2.3.2
which should be released very shortly[2] -- however most other MBR/MBW
implementations will work in CXF 2.3.1.


[1] http://www.jroller.com/gmazza/date/20110117
[2]
http://cxf.547215.n5.nabble.com/VOTE-Apache-CXF-2-3-2-tp3345633p3350807.html

>> 3. I checked the example Glenn suggested, however that example does NOT use
>> "ResponseReader". The method "useSimpleProxy" in "RESTClient.java", creates
>> a
>> client proxy from which it retrieves a collection of person objects; it
>> never
>> deals with a "Response" object. Did I miss something in the example?
>>

I apologize, the code I mentioned above will be in the *next* release of
the Talend examples, it actually uses brand new functionality put in by
Sergey in CXF 2.3.2.  An example of ResponseReader (from the upcoming
Talend samples) is below:

public void useSimpleProxy() {
System.out.println("Using a simple JAX-RS proxy to get all the persons...");
ResponseReader reader = new ResponseReader();
reader.setEntityClass(PersonCollection.class);

String webAppAddress = "http://localhost:" + port +
"/services/personservice";
PersonService proxy = JAXRSClientFactory.create(webAppAddress,
PersonService.class,
Collections.singletonList(reader));

// getPersons(a, b): a is zero-based start index, b is number of records
// to return (-1 for all)
Response resp = proxy.getPersons(0, -1);
if (resp.getStatus() == 200) {
PersonCollection personColl = (PersonCollection)resp.getEntity();
List<Person> persons = personColl.getList();
for (Iterator<Person> it = persons.iterator(); it.hasNext();) {
Person person = it.next();
System.out.println("ID " + person.getId() + " : " + person.getName() +
", age : "
+ person.getAge());
}
}
}

Again, though, this will unfortunately need to wait until CXF 2.3.2 is out.

HTH,
Glen




>> Thanks.
>>
>> -Dan
>>
>> ----- Original Message ----
>>
>>> From: Sergey Beryozkin<[hidden email]>
>>> To: [hidden email]
>>> Sent: Fri, January 21, 2011 6:37:54 AM
>>> Subject: Re: How to convert response input stream to java object
>>>
>>> ResponseReader is a custom MessageBodyReader<Response>  handler which  is
>>> registered on the client side, it allows to do a safe type casting, such
>>   as
>>> Response response = webClient.get();
>>> Book book =  (Book)Response.getEntity();
>>>
>>> It's possibe to write your own custom  Response reader with any CXF
>> version
>>> supporting the client api, but using the  ResponseReader makes it
>> simpler...
>>> Please check the demo Glen linked  to.
>>>
>>> Sergey
>>>
>>> On Fri, Jan 21, 2011 at 4:08 AM, Glen Mazza<[hidden email]>  wrote:
>>>
>>>> I  think ResponseReader, recently introduced in CXF 2.3.1, is your
>>   friend.
>>>> If you go to the Talend Service Factory (CXF wrap)  Examples[1], under
>>>> examples/jaxrs-advanced/client/..../RESTClient.java,  method
>> useSimpleProxy()
>>>> has it.
>>>>
>>>> Glen
>>>>
>>>> [1]  http://www.talend.com/resources/documentation.php#SF
>>>>
>>>>
>>>>   --
>>>> Glen Mazza
>>>> Software Engineer, Talend  (http://www.talend.com)
>>>> blog:  http://www.jroller.com/gmazza
>>>>
>>>>
>>>>
>>
>>
>>


--
Glen Mazza
Software Engineer, Talend (http://www.talend.com)
blog: http://www.jroller.com/gmazza


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Sergey Beryozkin
Having MessageBodyReader<Object> & MessageBodyWriter<Object> instead of
MessageBodyReader/MessageBodyWriter would work with any CXF version...

Benson and then myself worked a bit on ensuring that the process of choosing
the right JAX-RS provider checks the generic parameters so the fact some
providers may not even have them was kind of missed. Definitely not a big
issue

Cheers, Sergey

On Fri, Jan 21, 2011 at 5:44 PM, Glen Mazza <[hidden email]> wrote:

>
>  On Fri, Jan 21, 2011 at 4:34 PM, Dan King<[hidden email]>  wrote:
>>
>>  2. Where can I find examples of custom
>>> message body reader/writer implementation examples? I've searched
>>> everywhere and
>>> found nothing that helps in understanding how to implement a custom one.
>>>
>>
> If you need to go that route, Example 6-02 of the JAX-RS book examples[1]
> has a rather complex MessageBodyReader/Writer example.  Note this example
> had uncovered a bug that was quickly fixed in CXF 2.3.2 which should be
> released very shortly[2] -- however most other MBR/MBW implementations will
> work in CXF 2.3.1.
>
>
> [1] http://www.jroller.com/gmazza/date/20110117
> [2]
> http://cxf.547215.n5.nabble.com/VOTE-Apache-CXF-2-3-2-tp3345633p3350807.html
>
>
>  3. I checked the example Glenn suggested, however that example does NOT
>>> use
>>> "ResponseReader". The method "useSimpleProxy" in "RESTClient.java",
>>> creates
>>> a
>>> client proxy from which it retrieves a collection of person objects; it
>>> never
>>> deals with a "Response" object. Did I miss something in the example?
>>>
>>>
> I apologize, the code I mentioned above will be in the *next* release of
> the Talend examples, it actually uses brand new functionality put in by
> Sergey in CXF 2.3.2.  An example of ResponseReader (from the upcoming Talend
> samples) is below:
>
> public void useSimpleProxy() {
> System.out.println("Using a simple JAX-RS proxy to get all the
> persons...");
> ResponseReader reader = new ResponseReader();
> reader.setEntityClass(PersonCollection.class);
>
> String webAppAddress = "http://localhost:" + port +
> "/services/personservice";
> PersonService proxy = JAXRSClientFactory.create(webAppAddress,
> PersonService.class,
> Collections.singletonList(reader));
>
> // getPersons(a, b): a is zero-based start index, b is number of records
> // to return (-1 for all)
> Response resp = proxy.getPersons(0, -1);
> if (resp.getStatus() == 200) {
> PersonCollection personColl = (PersonCollection)resp.getEntity();
> List<Person> persons = personColl.getList();
> for (Iterator<Person> it = persons.iterator(); it.hasNext();) {
> Person person = it.next();
> System.out.println("ID " + person.getId() + " : " + person.getName() + ",
> age : "
> + person.getAge());
> }
> }
> }
>
> Again, though, this will unfortunately need to wait until CXF 2.3.2 is out.
>
> HTH,
> Glen
>
>
>
>
>
>  Thanks.
>>>
>>> -Dan
>>>
>>> ----- Original Message ----
>>>
>>>  From: Sergey Beryozkin<[hidden email]>
>>>> To: [hidden email]
>>>> Sent: Fri, January 21, 2011 6:37:54 AM
>>>> Subject: Re: How to convert response input stream to java object
>>>>
>>>> ResponseReader is a custom MessageBodyReader<Response>  handler which
>>>>  is
>>>> registered on the client side, it allows to do a safe type casting, such
>>>>
>>>  as
>>>
>>>> Response response = webClient.get();
>>>> Book book =  (Book)Response.getEntity();
>>>>
>>>> It's possibe to write your own custom  Response reader with any CXF
>>>>
>>> version
>>>
>>>> supporting the client api, but using the  ResponseReader makes it
>>>>
>>> simpler...
>>>
>>>> Please check the demo Glen linked  to.
>>>>
>>>> Sergey
>>>>
>>>> On Fri, Jan 21, 2011 at 4:08 AM, Glen Mazza<[hidden email]>  wrote:
>>>>
>>>>  I  think ResponseReader, recently introduced in CXF 2.3.1, is your
>>>>>
>>>>  friend.
>>>
>>>> If you go to the Talend Service Factory (CXF wrap)  Examples[1], under
>>>>> examples/jaxrs-advanced/client/..../RESTClient.java,  method
>>>>>
>>>> useSimpleProxy()
>>>
>>>> has it.
>>>>>
>>>>> Glen
>>>>>
>>>>> [1]  http://www.talend.com/resources/documentation.php#SF
>>>>>
>>>>>
>>>>>  --
>>>>> Glen Mazza
>>>>> Software Engineer, Talend  (http://www.talend.com)
>>>>> blog:  http://www.jroller.com/gmazza
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>>>
>>>
>
> --
> Glen Mazza
> Software Engineer, Talend (http://www.talend.com)
> blog: http://www.jroller.com/gmazza
>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

dan0
In reply to this post by Glen Mazza (Talend)
> An example of ResponseReader (from the upcoming

> Talend samples) is below:
> Again, though, this will unfortunately  need to wait until CXF 2.3.2 is  out.
>
> HTH,
> Glen

Thank you very much for the book suggestion and the ResponseReader example.
While I do understand the example, I'm having some difficulties getting it to
work, specifically, I'm continually getting the exception:


Cannot cast object  
'sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@181305e'  with
class 'sun.net.www.protocol.http.HttpURLConnection$HttpInputStream'  to class
'com.webprofiler.ws.dto.ProfileDto'


I have the cxf-bundle-minimal-2.3.2.jar in my classpath and the relative code is
below; do you see anything wrong?

        ResponseReader reader = new ResponseReader();
        reader.setEntityClass(ProfileDto.class);
        WebClientcustWebClient =
WebClient.create(webClient.getBaseURI().toString(),
Collections.singletonList(reader));
        Response response =
custWebClient.path("/search/profile").type("application/json").accept("application/json").post(criteria);

        if (response.getStatus() == 200 || response.getStatus() == 204) {
            ProfileDto results = (ProfileDto) response.getEntity();
            ....code to generate view...
        }

Thanks

-Dan



     
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Sergey Beryozkin
Hi

As it happens it does not currently work for WebClient - I did not even
think about writing a test for WebClient given that it was really needed for
a proxy case. With the WebClient you can do

Book book = wc.get(Book.class)
// returns the last Response, no remote invocation is done
Response r = wc.getResponse();

That said, I've got it fixed - thanks for spotting the problem...

Sergey


On Sun, Jan 23, 2011 at 1:45 AM, Dan King <[hidden email]> wrote:

> > An example of ResponseReader (from the upcoming
>
> > Talend samples) is below:
> > Again, though, this will unfortunately  need to wait until CXF 2.3.2 is
>  out.
> >
> > HTH,
> > Glen
>
> Thank you very much for the book suggestion and the ResponseReader example.
> While I do understand the example, I'm having some difficulties getting it
> to
> work, specifically, I'm continually getting the exception:
>
>
> Cannot cast object
> 'sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@181305e'
>  with
> class 'sun.net.www.protocol.http.HttpURLConnection$HttpInputStream'  to
> class
> 'com.webprofiler.ws.dto.ProfileDto'
>
>
> I have the cxf-bundle-minimal-2.3.2.jar in my classpath and the relative
> code is
> below; do you see anything wrong?
>
>        ResponseReader reader = new ResponseReader();
>        reader.setEntityClass(ProfileDto.class);
>        WebClientcustWebClient =
> WebClient.create(webClient.getBaseURI().toString(),
> Collections.singletonList(reader));
>        Response response =
>
> custWebClient.path("/search/profile").type("application/json").accept("application/json").post(criteria);
>
>        if (response.getStatus() == 200 || response.getStatus() == 204) {
>            ProfileDto results = (ProfileDto) response.getEntity();
>            ....code to generate view...
>        }
>
> Thanks
>
> -Dan
>
>
>
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

dan0
> ... With the WebClient you can do
>
> Book book =  wc.get(Book.class)
> // returns the last Response, no remote invocation is  done
> Response r = wc.getResponse();

This is what I'm currently doing; I thought of changing to using
"ResponseReader" since it seemed "cleaner" to check the response status before
attempting to read the message body. Is there any value in changing approaches?


     
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How to convert response input stream to java object

Sergey Beryozkin
Hi

On Mon, Jan 24, 2011 at 11:17 PM, Dan King <[hidden email]> wrote:

> > ... With the WebClient you can do
> >
> > Book book =  wc.get(Book.class)
> > // returns the last Response, no remote invocation is  done
> > Response r = wc.getResponse();
>
> This is what I'm currently doing; I thought of changing to using
> "ResponseReader" since it seemed "cleaner" to check the response status
> before
> attempting to read the message body. Is there any value in changing
> approaches?
>
>

wc.get(Book.class) will throw the ServerWebApplicationException in case of
the status >= 400. Currently 'null' will be returned in case of redirects,
unless CXF is configured to do the auto-redirects.

wc.getResponse(); will return the Response no matter what :-), unless a
client side error occurs, in which case you'll
get ClientWebApplicationException.

I guess ResponseReader can give a possibility to work with explicit
Responses consistently irrespectively whether proxies or WebClients are used
and indeed, as you said, it makes it easier to follow the 'check status
first' approach...

Cheers, Sergey
Loading...