You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Sergey Beryozkin <sb...@progress.com> on 2009/04/23 13:29:33 UTC

Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Hi,

One way is to register a message body writer for List  which will check if it contains String. It is somewhat primitive but very 
simple solution which will also scale (as far as handling lists with various types is concerned) quite well.
A more type safe way is to register a writer for List<String> and then wrap your list into a GenericEntity :

List<String> results = this.getX2dbiResults(fileContent);
return Response.ok(
new GenericEntity<List<String>>(results)).build();



cheers, Sergey


----- Original Message ----- 
From: "Raphael F." <ra...@gmail.com>
To: <us...@cxf.apache.org>
Sent: Monday, April 20, 2009 6:26 PM
Subject: Error : No message body writer found for response class : ArrayList. - A String is OK...


Hello everibody;

In my program, i send a file @ /postXML from a client class using
HttpClient and PostMethod objects. At server side, I have 2 String
objects to return (one with data queried, the second with debug data,
both are necessary) in a List<String> object to the client but I have
a problem... Here is the server side code :

[...]
@POST
@Path("/postXML")
public Response postXML(InputStream fileContent) {

List<String> results = this.getX2dbiResults(fileContent);
Response resp = Response.ok(results).build();

return resp;
}
[...]

At client side, the code is :

[...]
RequestEntity entity = new FileRequestEntity(input, "text/xml");
PostMethod post = new PostMethod("http://localhost:9000/postXML");
post.addRequestHeader("Accept", "text/xml");
post.setRequestEntity(entity);

HttpClient httpclient = new HttpClient();

try {
int result = httpclient.executeMethod(post);
System.out.println("Response status code: " + result);
System.out.println("Response body: ");
System.out.println(post.getResponseBodyAsString());
}
finally {
post.releaseConnection();
}
[...]

When i execute client class, I get this message :

Response status code: 500
Response body:
.No message body writer found for response class : ArrayList.

At server side, I have this information :
20 avr. 2009 18:37:16
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
writeResponseErrorMessage
.No message body writer found for response class : ArrayList.

When I use a String for the result in Response.ok(results).build(),
there is no error, so how is it possible to return another entity than
String (i.e. an ArrayList) into Response.ok().build() ?

Thanks for all.

-- 
Raphaël F.

L'avenir de nos Libertés Fondamentales passe par la défense de nos
Libertés Numériques !
Promouvoir et défendre le logiciel libre : http://www.april.org/
Les projets numériques liberticides du gouvernement français et de
l'Europe : http://www.laquadrature.net/
OpenOffice.org en images : http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
"Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
habitue." Méditez-y...


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Kruntz <ca...@ottolina.net>.

Sergey Beryozkin-2 wrote:
> 
> sure, if you use JAXRSServerFactoryBean then it has a setter accepting a
> list of providers.
> 

Thanks, Sergey.
This is what I did, and it works perfectly:

this.sfb = new JAXRSServerFactoryBean();
..
..
List providers = new ArrayList();
Object responseProvider = new ResponseProvider();
providers.add(responseProvider);
this.sfb.setProviders(providers);
..
..
this.sfb.create();

Cheers,
Carlo
-- 
View this message in context: http://www.nabble.com/Error-%3A-No-message-body-writer-found-for-response-class-%3A-ArrayList.----A-String-is-OK...-tp23141179p24646976.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi

>
>
> Sergey Beryozkin-2 wrote:
>>
>> If you do not want to use Spring then you can register your provider with
>> CxfNonSpringJaxrsServlet :
>>
> Is there a way to register the provider programmatically, without Spring?

sure, if you use JAXRSServerFactoryBean then it has a setter accepting a list of providers.
if you use CxfNonSpringJaxrsServlet then you can use jaxrs.providers parameter to register a list of provider class names or you can 
supply to it a JAXRS Application implementation if you prefer.

cheers, Sergey

>
> Thanks in advance.
> -- 
> View this message in context: 
> http://www.nabble.com/Error-%3A-No-message-body-writer-found-for-response-class-%3A-ArrayList.----A-String-is-OK...-tp23141179p24643368.html
> Sent from the cxf-user mailing list archive at Nabble.com.
> 


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Kruntz <ca...@ottolina.net>.

Sergey Beryozkin-2 wrote:
> 
> If you do not want to use Spring then you can register your provider with
> CxfNonSpringJaxrsServlet :
> 
 Is there a way to register the provider programmatically, without Spring?

Thanks in advance.
-- 
View this message in context: http://www.nabble.com/Error-%3A-No-message-body-writer-found-for-response-class-%3A-ArrayList.----A-String-is-OK...-tp23141179p24643368.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi

If you do not want to use Spring then you can register your provider with CxfNonSpringJaxrsServlet :

<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
</servlet-class>
<!-- resource classes -->
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
org.apache.cxf.systest.jaxrs.BookStore
</param-value>
</init-param>
<!-- providers -->
<init-param>
<param-name>jaxrs.providers</param-name>
<param-value>
org.apache.cxf.systest.jaxrs.BookStoreProvider
org.apache.cxf.systest.jaxrs.BookStoreProvider2
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

or in a more portable way :


<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>org.apache.cxf.systest.jaxrs.BookApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

in this case org.apache.cxf.systest.jaxrs.BookApplication is an implementation of JAX-RS Application, you can specify either 
singleton or per-request resource classes plus providers as well. Note, provider instances will have to be returned from 
Application.getSingletons() as we don't support per-request providers (that is, they won't be instantiated per every request), and 
indeed, the default scope for providers in JAXRS is singleton

cheers, Sergey


----- Original Message ----- 
From: "Raphael F." <ra...@gmail.com>
To: <us...@cxf.apache.org>
Sent: Wednesday, April 29, 2009 5:29 PM
Subject: Re: Error : No message body writer found for response class : ArrayList. - A String is OK...


Indeed, I expected it to be picked up automatically. But well, at this
moment, I'll try to not use this functionnality until I configure
Spring correctly if needed.

Don't hesitate to let me know if you implement this feature.

Thanks for all Sergey.


2009/4/29 Sergey Beryozkin <sb...@progress.com>:
> Hi,
>
> So how do you register this provider ? Do you do it from Spring ?
> Perhaps you expect it be picked up automatically ?
> We might add a support for picking up the providers through the
> class-scanning - I honestly don't like this feature though but
> I think we'll need to do it anyway as some users do expect it be picked up
> from a classpath...
>
> thanks, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Wednesday, April 29, 2009 4:59 PM
> Subject: Re: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hello,
>
> Despite the update of CXF to 2.2.1, I still have the same error. I've
> tried to change my MessageBodyWriter implementation as follows :
>
> ---------------
> @Provider
> @Produces("*/*")
> public class StringListBodyWriter implements
> MessageBodyWriter<ArrayList<String>> {
>
> public long getSize(ArrayList<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return -1;
> }
>
> public boolean isWriteable(Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return true;
> }
>
> public void writeTo(ArrayList<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType,
> MultivaluedMap<String, Object> httpHeaders,
> OutputStream entityStream) throws IOException,
> WebApplicationException {
> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
> entityStream));
> String ts = null;
> Iterator<String> i = t.iterator();
> while (i.hasNext()) {
> ts += i.next().toString();
> }
> bw.write(ts);
> bw.flush();
> }
> }
> ---------------
>
> But the same error occurs.
>
> At client side, I try to get the response body as an array of byte
> which I cast to a List of Strings, but for this moment, while error
> occurs, I can't check this step.
>
> So, what could I do ? Does something goes wrong with the code above ?
> Did I forgot a step, a class or another thing which I did not
> precised, or did I mistake ?
>
> Thanks for help.
>
> Raphael.
>
>
> 2009/4/28 Sergey Beryozkin <sb...@progress.com>:
>>
>> Hi Raphael
>>
>> It should work fine - but I forgot top tell you that I only added
>> genericEntity support very recently, as part of working on the TCK
>> compliance, sorry about it.
>>
>> CXF 2.2.1 has just been released - it should have this fix.
>>
>> I believe the only reason GenericEntity is there is that it allows users
>> to
>> write providers for parameterized types. It has the information about the
>> raw type and the generic type, and the runtime uses this information to
>> find
>> a matching provider.
>>
>> By the way, in getSize() you just need to return -1, unless you actually
>> know the (Content-Length) value. It's a hint to the runtime on how to set
>> a
>> Content-Length HTTP response header, if it's -1 then it will be up to the
>> underlying HTTP container on how to set it
>>
>> in isWriteable() there's no need to check for media types, as you already
>> set them in Produces(), but you might want to check that the genericType
>> is
>> String.class...
>>
>> cheers, Sergey
>>
>>
>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>> To: <us...@cxf.apache.org>
>> Sent: Tuesday, April 28, 2009 5:05 PM
>> Subject: Re: Error : No message body writer found for response class :
>> ArrayList. - A String is OK...
>>
>>
>> Hi Serguey,
>>
>> Thanks for your help. I'm just back from short holidays.
>>
>> So I've created a class implementing MessageBodyWriter interface for
>> it can accept List<String> entity, as shown below :
>>
>> -----------------------------------------------------------
>> @Provider
>> @Produces("text/xml,text/plain")
>> public class StringListBodyWriter implements
>> MessageBodyWriter<List<String>> {
>>
>> public long getSize(List<String> t, Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType) {
>> Iterator<String> i = t.iterator();
>> long size = 0;
>> while (i.hasNext()) {
>> size += i.next().length();
>> System.out.println("La taille de " + i + " est : "
>> + i.next().length());
>> }
>> return size;
>> }
>>
>> public boolean isWriteable(Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType) {
>> return type.equals(List.class)
>> && (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
>> .equals(MediaType.TEXT_XML_TYPE));
>> }
>>
>> public void writeTo(List<String> t, Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType,
>> MultivaluedMap<String, Object> httpHeaders,
>> OutputStream entityStream) throws IOException,
>> WebApplicationException {
>> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
>> entityStream));
>> String ts = null;
>> Iterator<String> i = t.iterator();
>> while (i.hasNext()) {
>> ts += i.next().toString();
>> System.out.println("La String tString est :\n" + ts);
>> }
>> bw.write(ts);
>> bw.flush();
>> }
>> }
>> -----------------------------------------------------------
>>
>> But, at runtime, I still have a similar error message :
>> ---------------------------
>> 28 avr. 2009 16:49:58
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>> writeResponseErrorMessage
>> ATTENTION: .No message body writer found for response class : ArrayList.
>> ---------------------------
>>
>> So how could the StringListBodyWriter class could be used when the
>> List based generic-entity Response is built ? I don't really see when
>> the StringListBodyWriter class is called :
>> ---------------------------
>> return Response.ok(new
>> GenericEntity<List<String>>(results){}).entity(results).build();
>> ---------------------------
>>
>> Thanks, Raphael.
>>
>>
>> 2009/4/23 Sergey Beryozkin <sb...@progress.com>:
>>>
>>> Hi,
>>>
>>> One way is to register a message body writer for List which will check if
>>> it contains String. It is somewhat primitive but very simple solution
>>> which
>>> will also scale (as far as handling lists with various types is
>>> concerned)
>>> quite well.
>>> A more type safe way is to register a writer for List<String> and then
>>> wrap
>>> your list into a GenericEntity :
>>>
>>> List<String> results = this.getX2dbiResults(fileContent);
>>> return Response.ok(
>>> new GenericEntity<List<String>>(results)).build();
>>>
>>>
>>>
>>> cheers, Sergey
>>>
>>>
>>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>>> To: <us...@cxf.apache.org>
>>> Sent: Monday, April 20, 2009 6:26 PM
>>> Subject: Error : No message body writer found for response class :
>>> ArrayList. - A String is OK...
>>>
>>>
>>> Hello everibody;
>>>
>>> In my program, i send a file @ /postXML from a client class using
>>> HttpClient and PostMethod objects. At server side, I have 2 String
>>> objects to return (one with data queried, the second with debug data,
>>> both are necessary) in a List<String> object to the client but I have
>>> a problem... Here is the server side code :
>>>
>>> [...]
>>> @POST
>>> @Path("/postXML")
>>> public Response postXML(InputStream fileContent) {
>>>
>>> List<String> results = this.getX2dbiResults(fileContent);
>>> Response resp = Response.ok(results).build();
>>>
>>> return resp;
>>> }
>>> [...]
>>>
>>> At client side, the code is :
>>>
>>> [...]
>>> RequestEntity entity = new FileRequestEntity(input, "text/xml");
>>> PostMethod post = new PostMethod("http://localhost:9000/postXML");
>>> post.addRequestHeader("Accept", "text/xml");
>>> post.setRequestEntity(entity);
>>>
>>> HttpClient httpclient = new HttpClient();
>>>
>>> try {
>>> int result = httpclient.executeMethod(post);
>>> System.out.println("Response status code: " + result);
>>> System.out.println("Response body: ");
>>> System.out.println(post.getResponseBodyAsString());
>>> }
>>> finally {
>>> post.releaseConnection();
>>> }
>>> [...]
>>>
>>> When i execute client class, I get this message :
>>>
>>> Response status code: 500
>>> Response body:
>>> .No message body writer found for response class : ArrayList.
>>>
>>> At server side, I have this information :
>>> 20 avr. 2009 18:37:16
>>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>>> writeResponseErrorMessage
>>> .No message body writer found for response class : ArrayList.
>>>
>>> When I use a String for the result in Response.ok(results).build(),
>>> there is no error, so how is it possible to return another entity than
>>> String (i.e. an ArrayList) into Response.ok().build() ?
>>>
>>> Thanks for all.
>>
>>
>
>
>
> --
> Raphaël F.
>
> L'avenir de nos Libertés Fondamentales passe par la défense de nos
> Libertés Numériques !
> Promouvoir et défendre le logiciel libre : http://www.april.org/
> Les projets numériques liberticides du gouvernement français et de
> l'Europe : http://www.laquadrature.net/
> OpenOffice.org en images :
> http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
> "Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
> habitue." Méditez-y...
>



-- 
Raphaël F.

L'avenir de nos Libertés Fondamentales passe par la défense de nos
Libertés Numériques !
Promouvoir et défendre le logiciel libre : http://www.april.org/
Les projets numériques liberticides du gouvernement français et de
l'Europe : http://www.laquadrature.net/
OpenOffice.org en images : http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
"Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
habitue." Méditez-y... 


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by "Raphael F." <ra...@gmail.com>.
Indeed, I expected it to be picked up automatically. But well, at this
moment, I'll try to not use this functionnality until I configure
Spring correctly if needed.

Don't hesitate to let me know if you implement this feature.

Thanks for all Sergey.


2009/4/29 Sergey Beryozkin <sb...@progress.com>:
> Hi,
>
> So how do you register this provider ? Do you do it from Spring ?
> Perhaps you expect it be picked up automatically ?
> We might add a support for picking up the providers through the
> class-scanning - I honestly don't like this feature though but
> I think we'll need to do it anyway as some users do expect it be picked up
> from a classpath...
>
> thanks, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Wednesday, April 29, 2009 4:59 PM
> Subject: Re: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hello,
>
> Despite the update of CXF to 2.2.1, I still have the same error. I've
> tried to change my MessageBodyWriter implementation as follows :
>
> ---------------
> @Provider
> @Produces("*/*")
> public class StringListBodyWriter implements
> MessageBodyWriter<ArrayList<String>> {
>
> public long getSize(ArrayList<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return -1;
> }
>
> public boolean isWriteable(Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return true;
> }
>
> public void writeTo(ArrayList<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType,
> MultivaluedMap<String, Object> httpHeaders,
> OutputStream entityStream) throws IOException,
> WebApplicationException {
> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
> entityStream));
> String ts = null;
> Iterator<String> i = t.iterator();
> while (i.hasNext()) {
> ts += i.next().toString();
> }
> bw.write(ts);
> bw.flush();
> }
> }
> ---------------
>
> But the same error occurs.
>
> At client side, I try to get the response body as an array of byte
> which I cast to a List of Strings, but for this moment, while error
> occurs, I can't check this step.
>
> So, what could I do ? Does something goes wrong with the code above ?
> Did I forgot a step, a class or another thing which I did not
> precised, or did I mistake ?
>
> Thanks for help.
>
> Raphael.
>
>
> 2009/4/28 Sergey Beryozkin <sb...@progress.com>:
>>
>> Hi Raphael
>>
>> It should work fine - but I forgot top tell you that I only added
>> genericEntity support very recently, as part of working on the TCK
>> compliance, sorry about it.
>>
>> CXF 2.2.1 has just been released - it should have this fix.
>>
>> I believe the only reason GenericEntity is there is that it allows users
>> to
>> write providers for parameterized types. It has the information about the
>> raw type and the generic type, and the runtime uses this information to
>> find
>> a matching provider.
>>
>> By the way, in getSize() you just need to return -1, unless you actually
>> know the (Content-Length) value. It's a hint to the runtime on how to set
>> a
>> Content-Length HTTP response header, if it's -1 then it will be up to the
>> underlying HTTP container on how to set it
>>
>> in isWriteable() there's no need to check for media types, as you already
>> set them in Produces(), but you might want to check that the genericType
>> is
>> String.class...
>>
>> cheers, Sergey
>>
>>
>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>> To: <us...@cxf.apache.org>
>> Sent: Tuesday, April 28, 2009 5:05 PM
>> Subject: Re: Error : No message body writer found for response class :
>> ArrayList. - A String is OK...
>>
>>
>> Hi Serguey,
>>
>> Thanks for your help. I'm just back from short holidays.
>>
>> So I've created a class implementing MessageBodyWriter interface for
>> it can accept List<String> entity, as shown below :
>>
>> -----------------------------------------------------------
>> @Provider
>> @Produces("text/xml,text/plain")
>> public class StringListBodyWriter implements
>> MessageBodyWriter<List<String>> {
>>
>> public long getSize(List<String> t, Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType) {
>> Iterator<String> i = t.iterator();
>> long size = 0;
>> while (i.hasNext()) {
>> size += i.next().length();
>> System.out.println("La taille de " + i + " est : "
>> + i.next().length());
>> }
>> return size;
>> }
>>
>> public boolean isWriteable(Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType) {
>> return type.equals(List.class)
>> && (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
>> .equals(MediaType.TEXT_XML_TYPE));
>> }
>>
>> public void writeTo(List<String> t, Class<?> type, Type genericType,
>> Annotation[] annotations, MediaType mediaType,
>> MultivaluedMap<String, Object> httpHeaders,
>> OutputStream entityStream) throws IOException,
>> WebApplicationException {
>> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
>> entityStream));
>> String ts = null;
>> Iterator<String> i = t.iterator();
>> while (i.hasNext()) {
>> ts += i.next().toString();
>> System.out.println("La String tString est :\n" + ts);
>> }
>> bw.write(ts);
>> bw.flush();
>> }
>> }
>> -----------------------------------------------------------
>>
>> But, at runtime, I still have a similar error message :
>> ---------------------------
>> 28 avr. 2009 16:49:58
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>> writeResponseErrorMessage
>> ATTENTION: .No message body writer found for response class : ArrayList.
>> ---------------------------
>>
>> So how could the StringListBodyWriter class could be used when the
>> List based generic-entity Response is built ? I don't really see when
>> the StringListBodyWriter class is called :
>> ---------------------------
>> return Response.ok(new
>> GenericEntity<List<String>>(results){}).entity(results).build();
>> ---------------------------
>>
>> Thanks, Raphael.
>>
>>
>> 2009/4/23 Sergey Beryozkin <sb...@progress.com>:
>>>
>>> Hi,
>>>
>>> One way is to register a message body writer for List which will check if
>>> it contains String. It is somewhat primitive but very simple solution
>>> which
>>> will also scale (as far as handling lists with various types is
>>> concerned)
>>> quite well.
>>> A more type safe way is to register a writer for List<String> and then
>>> wrap
>>> your list into a GenericEntity :
>>>
>>> List<String> results = this.getX2dbiResults(fileContent);
>>> return Response.ok(
>>> new GenericEntity<List<String>>(results)).build();
>>>
>>>
>>>
>>> cheers, Sergey
>>>
>>>
>>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>>> To: <us...@cxf.apache.org>
>>> Sent: Monday, April 20, 2009 6:26 PM
>>> Subject: Error : No message body writer found for response class :
>>> ArrayList. - A String is OK...
>>>
>>>
>>> Hello everibody;
>>>
>>> In my program, i send a file @ /postXML from a client class using
>>> HttpClient and PostMethod objects. At server side, I have 2 String
>>> objects to return (one with data queried, the second with debug data,
>>> both are necessary) in a List<String> object to the client but I have
>>> a problem... Here is the server side code :
>>>
>>> [...]
>>> @POST
>>> @Path("/postXML")
>>> public Response postXML(InputStream fileContent) {
>>>
>>> List<String> results = this.getX2dbiResults(fileContent);
>>> Response resp = Response.ok(results).build();
>>>
>>> return resp;
>>> }
>>> [...]
>>>
>>> At client side, the code is :
>>>
>>> [...]
>>> RequestEntity entity = new FileRequestEntity(input, "text/xml");
>>> PostMethod post = new PostMethod("http://localhost:9000/postXML");
>>> post.addRequestHeader("Accept", "text/xml");
>>> post.setRequestEntity(entity);
>>>
>>> HttpClient httpclient = new HttpClient();
>>>
>>> try {
>>> int result = httpclient.executeMethod(post);
>>> System.out.println("Response status code: " + result);
>>> System.out.println("Response body: ");
>>> System.out.println(post.getResponseBodyAsString());
>>> }
>>> finally {
>>> post.releaseConnection();
>>> }
>>> [...]
>>>
>>> When i execute client class, I get this message :
>>>
>>> Response status code: 500
>>> Response body:
>>> .No message body writer found for response class : ArrayList.
>>>
>>> At server side, I have this information :
>>> 20 avr. 2009 18:37:16
>>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>>> writeResponseErrorMessage
>>> .No message body writer found for response class : ArrayList.
>>>
>>> When I use a String for the result in Response.ok(results).build(),
>>> there is no error, so how is it possible to return another entity than
>>> String (i.e. an ArrayList) into Response.ok().build() ?
>>>
>>> Thanks for all.
>>
>>
>
>
>
> --
> Raphaël F.
>
> L'avenir de nos Libertés Fondamentales passe par la défense de nos
> Libertés Numériques !
> Promouvoir et défendre le logiciel libre : http://www.april.org/
> Les projets numériques liberticides du gouvernement français et de
> l'Europe : http://www.laquadrature.net/
> OpenOffice.org en images :
> http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
> "Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
> habitue." Méditez-y...
>



-- 
Raphaël F.

L'avenir de nos Libertés Fondamentales passe par la défense de nos
Libertés Numériques !
Promouvoir et défendre le logiciel libre : http://www.april.org/
Les projets numériques liberticides du gouvernement français et de
l'Europe : http://www.laquadrature.net/
OpenOffice.org en images : http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
"Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
habitue." Méditez-y...

Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi,

So how do you register this provider ? Do you do it from Spring ?
Perhaps you expect it be picked up automatically ?
We might add a support for picking up the providers through the class-scanning - I honestly don't like this feature though but
I think we'll need to do it anyway as some users do expect it be picked up from a classpath...

thanks, Sergey


----- Original Message ----- 
From: "Raphael F." <ra...@gmail.com>
To: <us...@cxf.apache.org>
Sent: Wednesday, April 29, 2009 4:59 PM
Subject: Re: Error : No message body writer found for response class : ArrayList. - A String is OK...


Hello,

Despite the update of CXF to 2.2.1, I still have the same error. I've
tried to change my MessageBodyWriter implementation as follows :

---------------
@Provider
@Produces("*/*")
public class StringListBodyWriter implements
MessageBodyWriter<ArrayList<String>> {

public long getSize(ArrayList<String> t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}

public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}

public void writeTo(ArrayList<String> t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
entityStream));
String ts = null;
Iterator<String> i = t.iterator();
while (i.hasNext()) {
ts += i.next().toString();
}
bw.write(ts);
bw.flush();
}
}
---------------

But the same error occurs.

At client side, I try to get the response body as an array of byte
which I cast to a List of Strings, but for this moment, while error
occurs, I can't check this step.

So, what could I do ? Does something goes wrong with the code above ?
Did I forgot a step, a class or another thing which I did not
precised, or did I mistake ?

Thanks for help.

Raphael.


2009/4/28 Sergey Beryozkin <sb...@progress.com>:
> Hi Raphael
>
> It should work fine - but I forgot top tell you that I only added
> genericEntity support very recently, as part of working on the TCK
> compliance, sorry about it.
>
> CXF 2.2.1 has just been released - it should have this fix.
>
> I believe the only reason GenericEntity is there is that it allows users to
> write providers for parameterized types. It has the information about the
> raw type and the generic type, and the runtime uses this information to find
> a matching provider.
>
> By the way, in getSize() you just need to return -1, unless you actually
> know the (Content-Length) value. It's a hint to the runtime on how to set a
> Content-Length HTTP response header, if it's -1 then it will be up to the
> underlying HTTP container on how to set it
>
> in isWriteable() there's no need to check for media types, as you already
> set them in Produces(), but you might want to check that the genericType is
> String.class...
>
> cheers, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Tuesday, April 28, 2009 5:05 PM
> Subject: Re: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hi Serguey,
>
> Thanks for your help. I'm just back from short holidays.
>
> So I've created a class implementing MessageBodyWriter interface for
> it can accept List<String> entity, as shown below :
>
> -----------------------------------------------------------
> @Provider
> @Produces("text/xml,text/plain")
> public class StringListBodyWriter implements
> MessageBodyWriter<List<String>> {
>
> public long getSize(List<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> Iterator<String> i = t.iterator();
> long size = 0;
> while (i.hasNext()) {
> size += i.next().length();
> System.out.println("La taille de " + i + " est : "
> + i.next().length());
> }
> return size;
> }
>
> public boolean isWriteable(Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return type.equals(List.class)
> && (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
> .equals(MediaType.TEXT_XML_TYPE));
> }
>
> public void writeTo(List<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType,
> MultivaluedMap<String, Object> httpHeaders,
> OutputStream entityStream) throws IOException,
> WebApplicationException {
> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
> entityStream));
> String ts = null;
> Iterator<String> i = t.iterator();
> while (i.hasNext()) {
> ts += i.next().toString();
> System.out.println("La String tString est :\n" + ts);
> }
> bw.write(ts);
> bw.flush();
> }
> }
> -----------------------------------------------------------
>
> But, at runtime, I still have a similar error message :
> ---------------------------
> 28 avr. 2009 16:49:58
> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
> writeResponseErrorMessage
> ATTENTION: .No message body writer found for response class : ArrayList.
> ---------------------------
>
> So how could the StringListBodyWriter class could be used when the
> List based generic-entity Response is built ? I don't really see when
> the StringListBodyWriter class is called :
> ---------------------------
> return Response.ok(new
> GenericEntity<List<String>>(results){}).entity(results).build();
> ---------------------------
>
> Thanks, Raphael.
>
>
> 2009/4/23 Sergey Beryozkin <sb...@progress.com>:
>>
>> Hi,
>>
>> One way is to register a message body writer for List which will check if
>> it contains String. It is somewhat primitive but very simple solution
>> which
>> will also scale (as far as handling lists with various types is concerned)
>> quite well.
>> A more type safe way is to register a writer for List<String> and then
>> wrap
>> your list into a GenericEntity :
>>
>> List<String> results = this.getX2dbiResults(fileContent);
>> return Response.ok(
>> new GenericEntity<List<String>>(results)).build();
>>
>>
>>
>> cheers, Sergey
>>
>>
>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>> To: <us...@cxf.apache.org>
>> Sent: Monday, April 20, 2009 6:26 PM
>> Subject: Error : No message body writer found for response class :
>> ArrayList. - A String is OK...
>>
>>
>> Hello everibody;
>>
>> In my program, i send a file @ /postXML from a client class using
>> HttpClient and PostMethod objects. At server side, I have 2 String
>> objects to return (one with data queried, the second with debug data,
>> both are necessary) in a List<String> object to the client but I have
>> a problem... Here is the server side code :
>>
>> [...]
>> @POST
>> @Path("/postXML")
>> public Response postXML(InputStream fileContent) {
>>
>> List<String> results = this.getX2dbiResults(fileContent);
>> Response resp = Response.ok(results).build();
>>
>> return resp;
>> }
>> [...]
>>
>> At client side, the code is :
>>
>> [...]
>> RequestEntity entity = new FileRequestEntity(input, "text/xml");
>> PostMethod post = new PostMethod("http://localhost:9000/postXML");
>> post.addRequestHeader("Accept", "text/xml");
>> post.setRequestEntity(entity);
>>
>> HttpClient httpclient = new HttpClient();
>>
>> try {
>> int result = httpclient.executeMethod(post);
>> System.out.println("Response status code: " + result);
>> System.out.println("Response body: ");
>> System.out.println(post.getResponseBodyAsString());
>> }
>> finally {
>> post.releaseConnection();
>> }
>> [...]
>>
>> When i execute client class, I get this message :
>>
>> Response status code: 500
>> Response body:
>> .No message body writer found for response class : ArrayList.
>>
>> At server side, I have this information :
>> 20 avr. 2009 18:37:16
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>> writeResponseErrorMessage
>> .No message body writer found for response class : ArrayList.
>>
>> When I use a String for the result in Response.ok(results).build(),
>> there is no error, so how is it possible to return another entity than
>> String (i.e. an ArrayList) into Response.ok().build() ?
>>
>> Thanks for all.
>
>



-- 
Raphaël F.

L'avenir de nos Libertés Fondamentales passe par la défense de nos
Libertés Numériques !
Promouvoir et défendre le logiciel libre : http://www.april.org/
Les projets numériques liberticides du gouvernement français et de
l'Europe : http://www.laquadrature.net/
OpenOffice.org en images : http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
"Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
habitue." Méditez-y... 


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by "Raphael F." <ra...@gmail.com>.
Hello,

Despite the update of CXF to 2.2.1, I still have the same error. I've
tried to change my MessageBodyWriter implementation as follows :

---------------
@Provider
@Produces("*/*")
public class StringListBodyWriter implements
		MessageBodyWriter<ArrayList<String>> {

	public long getSize(ArrayList<String> t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return -1;
	}

	public boolean isWriteable(Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return true;
	}

	public void writeTo(ArrayList<String> t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders,
			OutputStream entityStream) throws IOException,
			WebApplicationException {
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
				entityStream));
		String ts = null;
		Iterator<String> i = t.iterator();
		while (i.hasNext()) {
			ts += i.next().toString();
		}
		bw.write(ts);
		bw.flush();
	}
}
---------------

But the same error occurs.

At client side, I try to get the response body as an array of byte
which I cast to a List of Strings, but for this moment, while error
occurs, I can't check this step.

So, what could I do ? Does something goes wrong with the code above ?
Did I forgot a step, a class or another thing which I did not
precised, or did I mistake ?

Thanks for help.

Raphael.


2009/4/28 Sergey Beryozkin <sb...@progress.com>:
> Hi Raphael
>
> It should work fine - but I forgot top tell you that I only added
> genericEntity support very recently, as part of working on the TCK
> compliance, sorry about it.
>
> CXF 2.2.1 has just been released - it should have this fix.
>
> I believe the only reason GenericEntity is there is that it allows users to
> write providers for parameterized types. It has the information about the
> raw type and the generic type, and the runtime uses this information to find
> a matching provider.
>
> By the way, in getSize() you just need to return -1, unless you actually
> know the (Content-Length) value. It's a hint to the runtime on how to set a
> Content-Length HTTP response header, if it's -1 then it will be up to the
> underlying HTTP container on how to set it
>
> in isWriteable() there's no need to check for media types, as you already
> set them in Produces(), but you might want to check that the genericType is
> String.class...
>
> cheers, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Tuesday, April 28, 2009 5:05 PM
> Subject: Re: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hi Serguey,
>
> Thanks for your help. I'm just back from short holidays.
>
> So I've created a class implementing MessageBodyWriter interface for
> it can accept List<String> entity, as shown below :
>
> -----------------------------------------------------------
> @Provider
> @Produces("text/xml,text/plain")
> public class StringListBodyWriter implements
> MessageBodyWriter<List<String>> {
>
> public long getSize(List<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> Iterator<String> i = t.iterator();
> long size = 0;
> while (i.hasNext()) {
> size += i.next().length();
> System.out.println("La taille de " + i + " est : "
> + i.next().length());
> }
> return size;
> }
>
> public boolean isWriteable(Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return type.equals(List.class)
> && (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
> .equals(MediaType.TEXT_XML_TYPE));
> }
>
> public void writeTo(List<String> t, Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType,
> MultivaluedMap<String, Object> httpHeaders,
> OutputStream entityStream) throws IOException,
> WebApplicationException {
> BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
> entityStream));
> String ts = null;
> Iterator<String> i = t.iterator();
> while (i.hasNext()) {
> ts += i.next().toString();
> System.out.println("La String tString est :\n" + ts);
> }
> bw.write(ts);
> bw.flush();
> }
> }
> -----------------------------------------------------------
>
> But, at runtime, I still have a similar error message :
> ---------------------------
> 28 avr. 2009 16:49:58
> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
> writeResponseErrorMessage
> ATTENTION: .No message body writer found for response class : ArrayList.
> ---------------------------
>
> So how could the StringListBodyWriter class could be used when the
> List based generic-entity Response is built ? I don't really see when
> the StringListBodyWriter class is called :
> ---------------------------
> return Response.ok(new
> GenericEntity<List<String>>(results){}).entity(results).build();
> ---------------------------
>
> Thanks, Raphael.
>
>
> 2009/4/23 Sergey Beryozkin <sb...@progress.com>:
>>
>> Hi,
>>
>> One way is to register a message body writer for List which will check if
>> it contains String. It is somewhat primitive but very simple solution
>> which
>> will also scale (as far as handling lists with various types is concerned)
>> quite well.
>> A more type safe way is to register a writer for List<String> and then
>> wrap
>> your list into a GenericEntity :
>>
>> List<String> results = this.getX2dbiResults(fileContent);
>> return Response.ok(
>> new GenericEntity<List<String>>(results)).build();
>>
>>
>>
>> cheers, Sergey
>>
>>
>> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
>> To: <us...@cxf.apache.org>
>> Sent: Monday, April 20, 2009 6:26 PM
>> Subject: Error : No message body writer found for response class :
>> ArrayList. - A String is OK...
>>
>>
>> Hello everibody;
>>
>> In my program, i send a file @ /postXML from a client class using
>> HttpClient and PostMethod objects. At server side, I have 2 String
>> objects to return (one with data queried, the second with debug data,
>> both are necessary) in a List<String> object to the client but I have
>> a problem... Here is the server side code :
>>
>> [...]
>> @POST
>> @Path("/postXML")
>> public Response postXML(InputStream fileContent) {
>>
>> List<String> results = this.getX2dbiResults(fileContent);
>> Response resp = Response.ok(results).build();
>>
>> return resp;
>> }
>> [...]
>>
>> At client side, the code is :
>>
>> [...]
>> RequestEntity entity = new FileRequestEntity(input, "text/xml");
>> PostMethod post = new PostMethod("http://localhost:9000/postXML");
>> post.addRequestHeader("Accept", "text/xml");
>> post.setRequestEntity(entity);
>>
>> HttpClient httpclient = new HttpClient();
>>
>> try {
>> int result = httpclient.executeMethod(post);
>> System.out.println("Response status code: " + result);
>> System.out.println("Response body: ");
>> System.out.println(post.getResponseBodyAsString());
>> }
>> finally {
>> post.releaseConnection();
>> }
>> [...]
>>
>> When i execute client class, I get this message :
>>
>> Response status code: 500
>> Response body:
>> .No message body writer found for response class : ArrayList.
>>
>> At server side, I have this information :
>> 20 avr. 2009 18:37:16
>> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
>> writeResponseErrorMessage
>> .No message body writer found for response class : ArrayList.
>>
>> When I use a String for the result in Response.ok(results).build(),
>> there is no error, so how is it possible to return another entity than
>> String (i.e. an ArrayList) into Response.ok().build() ?
>>
>> Thanks for all.
>
>



-- 
Raphaël F.

L'avenir de nos Libertés Fondamentales passe par la défense de nos
Libertés Numériques !
Promouvoir et défendre le logiciel libre : http://www.april.org/
Les projets numériques liberticides du gouvernement français et de
l'Europe : http://www.laquadrature.net/
OpenOffice.org en images : http://www.csdm.qc.ca/sitsat-mtl/openoffice/index.htm
"Ce qu'il y a de scandaleux dans le scandale, c'est qu'on s'y
habitue." Méditez-y...

Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Raphael

It should work fine - but I forgot top tell you that I only added genericEntity support very recently, as part of working on the TCK 
compliance, sorry about it.

CXF 2.2.1 has just been released - it should have this fix.

I believe the only reason GenericEntity is there is that it allows users to write providers for parameterized types. It has the 
information about the raw type and the generic type, and the runtime uses this information to find a matching provider.

By the way, in getSize() you just need to return -1, unless you actually know the (Content-Length) value. It's a hint to the runtime 
on how to set a Content-Length HTTP response header, if it's -1 then it will be up to the underlying HTTP container on how to set it

in isWriteable() there's no need to check for media types, as you already set them in Produces(), but you might want to check that 
the genericType is String.class...

cheers, Sergey


----- Original Message ----- 
From: "Raphael F." <ra...@gmail.com>
To: <us...@cxf.apache.org>
Sent: Tuesday, April 28, 2009 5:05 PM
Subject: Re: Error : No message body writer found for response class : ArrayList. - A String is OK...


Hi Serguey,

Thanks for your help. I'm just back from short holidays.

So I've created a class implementing MessageBodyWriter interface for
it can accept List<String> entity, as shown below :

-----------------------------------------------------------
@Provider
@Produces("text/xml,text/plain")
public class StringListBodyWriter implements
MessageBodyWriter<List<String>> {

public long getSize(List<String> t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
Iterator<String> i = t.iterator();
long size = 0;
while (i.hasNext()) {
size += i.next().length();
System.out.println("La taille de " + i + " est : "
+ i.next().length());
}
return size;
}

public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return type.equals(List.class)
&& (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
.equals(MediaType.TEXT_XML_TYPE));
}

public void writeTo(List<String> t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
entityStream));
String ts = null;
Iterator<String> i = t.iterator();
while (i.hasNext()) {
ts += i.next().toString();
System.out.println("La String tString est :\n" + ts);
}
bw.write(ts);
bw.flush();
}
}
-----------------------------------------------------------

But, at runtime, I still have a similar error message :
---------------------------
28 avr. 2009 16:49:58
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
writeResponseErrorMessage
ATTENTION: .No message body writer found for response class : ArrayList.
---------------------------

So how could the StringListBodyWriter class could be used when the
List based generic-entity Response is built ? I don't really see when
the StringListBodyWriter class is called :
---------------------------
return Response.ok(new
GenericEntity<List<String>>(results){}).entity(results).build();
---------------------------

Thanks, Raphael.


2009/4/23 Sergey Beryozkin <sb...@progress.com>:
> Hi,
>
> One way is to register a message body writer for List which will check if
> it contains String. It is somewhat primitive but very simple solution which
> will also scale (as far as handling lists with various types is concerned)
> quite well.
> A more type safe way is to register a writer for List<String> and then wrap
> your list into a GenericEntity :
>
> List<String> results = this.getX2dbiResults(fileContent);
> return Response.ok(
> new GenericEntity<List<String>>(results)).build();
>
>
>
> cheers, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Monday, April 20, 2009 6:26 PM
> Subject: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hello everibody;
>
> In my program, i send a file @ /postXML from a client class using
> HttpClient and PostMethod objects. At server side, I have 2 String
> objects to return (one with data queried, the second with debug data,
> both are necessary) in a List<String> object to the client but I have
> a problem... Here is the server side code :
>
> [...]
> @POST
> @Path("/postXML")
> public Response postXML(InputStream fileContent) {
>
> List<String> results = this.getX2dbiResults(fileContent);
> Response resp = Response.ok(results).build();
>
> return resp;
> }
> [...]
>
> At client side, the code is :
>
> [...]
> RequestEntity entity = new FileRequestEntity(input, "text/xml");
> PostMethod post = new PostMethod("http://localhost:9000/postXML");
> post.addRequestHeader("Accept", "text/xml");
> post.setRequestEntity(entity);
>
> HttpClient httpclient = new HttpClient();
>
> try {
> int result = httpclient.executeMethod(post);
> System.out.println("Response status code: " + result);
> System.out.println("Response body: ");
> System.out.println(post.getResponseBodyAsString());
> }
> finally {
> post.releaseConnection();
> }
> [...]
>
> When i execute client class, I get this message :
>
> Response status code: 500
> Response body:
> .No message body writer found for response class : ArrayList.
>
> At server side, I have this information :
> 20 avr. 2009 18:37:16
> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
> writeResponseErrorMessage
> .No message body writer found for response class : ArrayList.
>
> When I use a String for the result in Response.ok(results).build(),
> there is no error, so how is it possible to return another entity than
> String (i.e. an ArrayList) into Response.ok().build() ?
>
> Thanks for all. 


Re: Error : No message body writer found for response class : ArrayList. - A String is OK...

Posted by "Raphael F." <ra...@gmail.com>.
Hi Serguey,

Thanks for your help. I'm just back from short holidays.

So I've created a class implementing MessageBodyWriter interface for
it can accept List<String> entity, as shown below :

-----------------------------------------------------------
@Provider
@Produces("text/xml,text/plain")
public class StringListBodyWriter implements
		MessageBodyWriter<List<String>> {

	public long getSize(List<String> t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		Iterator<String> i = t.iterator();
		long size = 0;
		while (i.hasNext()) {
			size += i.next().length();
			System.out.println("La taille de " + i + " est : "
					+ i.next().length());
		}
		return size;
	}

	public boolean isWriteable(Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType) {
		return type.equals(List.class)
				&& (mediaType.equals(MediaType.TEXT_PLAIN_TYPE) | mediaType
						.equals(MediaType.TEXT_XML_TYPE));
	}

	public void writeTo(List<String> t, Class<?> type, Type genericType,
			Annotation[] annotations, MediaType mediaType,
			MultivaluedMap<String, Object> httpHeaders,
			OutputStream entityStream) throws IOException,
			WebApplicationException {
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
				entityStream));
		String ts = null;
		Iterator<String> i = t.iterator();
		while (i.hasNext()) {
			ts += i.next().toString();
			System.out.println("La String tString est :\n" + ts);
		}
		bw.write(ts);
		bw.flush();
	}
}
-----------------------------------------------------------

But, at runtime, I still have a similar error message :
---------------------------
28 avr. 2009 16:49:58
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
writeResponseErrorMessage
ATTENTION: .No message body writer found for response class : ArrayList.
---------------------------

So how could the StringListBodyWriter class could be used when the
List based generic-entity Response is built ? I don't really see when
the StringListBodyWriter class is called :
---------------------------
			return Response.ok(new
GenericEntity<List<String>>(results){}).entity(results).build();
---------------------------

Thanks, Raphael.


2009/4/23 Sergey Beryozkin <sb...@progress.com>:
> Hi,
>
> One way is to register a message body writer for List  which will check if
> it contains String. It is somewhat primitive but very simple solution which
> will also scale (as far as handling lists with various types is concerned)
> quite well.
> A more type safe way is to register a writer for List<String> and then wrap
> your list into a GenericEntity :
>
> List<String> results = this.getX2dbiResults(fileContent);
> return Response.ok(
> new GenericEntity<List<String>>(results)).build();
>
>
>
> cheers, Sergey
>
>
> ----- Original Message ----- From: "Raphael F." <ra...@gmail.com>
> To: <us...@cxf.apache.org>
> Sent: Monday, April 20, 2009 6:26 PM
> Subject: Error : No message body writer found for response class :
> ArrayList. - A String is OK...
>
>
> Hello everibody;
>
> In my program, i send a file @ /postXML from a client class using
> HttpClient and PostMethod objects. At server side, I have 2 String
> objects to return (one with data queried, the second with debug data,
> both are necessary) in a List<String> object to the client but I have
> a problem... Here is the server side code :
>
> [...]
> @POST
> @Path("/postXML")
> public Response postXML(InputStream fileContent) {
>
> List<String> results = this.getX2dbiResults(fileContent);
> Response resp = Response.ok(results).build();
>
> return resp;
> }
> [...]
>
> At client side, the code is :
>
> [...]
> RequestEntity entity = new FileRequestEntity(input, "text/xml");
> PostMethod post = new PostMethod("http://localhost:9000/postXML");
> post.addRequestHeader("Accept", "text/xml");
> post.setRequestEntity(entity);
>
> HttpClient httpclient = new HttpClient();
>
> try {
> int result = httpclient.executeMethod(post);
> System.out.println("Response status code: " + result);
> System.out.println("Response body: ");
> System.out.println(post.getResponseBodyAsString());
> }
> finally {
> post.releaseConnection();
> }
> [...]
>
> When i execute client class, I get this message :
>
> Response status code: 500
> Response body:
> .No message body writer found for response class : ArrayList.
>
> At server side, I have this information :
> 20 avr. 2009 18:37:16
> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor
> writeResponseErrorMessage
> .No message body writer found for response class : ArrayList.
>
> When I use a String for the result in Response.ok(results).build(),
> there is no error, so how is it possible to return another entity than
> String (i.e. an ArrayList) into Response.ok().build() ?
>
> Thanks for all.