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." <[email protected]>
To: <[email protected]>
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 <[email protected]>:
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." <[email protected]>
To: <[email protected]>
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.