Well, anybody can say this question is already asked and answered. Never mind I also found them.
- JAX-RS: How to automatically serialize a collection when returning a Response object?
- Using Java-generics template type in RESTful Response object via GenericEntity<List<T>>
I'm not confused with the way of responding with an List<T>
but just not convinced about the portability.
Let's say I have a nicely annotated entity looks like this.
@XmlRootElement
public class Stock {
@XmlAttribute
private Long id;
}
List<Stock>
When do like this,
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Stock> readStocks() {
final List<Stock> list = getStocks();
return list;
}
As far as know, GlassFish and WileFly works.
<stocks> <!-- automatic plural? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</stocks>
<collection> <!-- fixed? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</collection>
and JSON, (it could be vary by providers, i think)
[
{
"id": 1
},
{
"id": 2
}
]
GenericEntity<List<Stock>>
Sometime I see a problem when the container couldn't find a MessageBodyWriter
. So that I do like this.
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public GenericEntity<List<T>> readStocks() {
return new GenericEntity<List<Stock>>(getStocks()) {};
}
or
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response readStocks() {
return Response.ok(new GenericEntity<List<Stock>>(getStocks()) {}).build();
}
WrapperClass
@XmlRootElement
public class Stocks {
@XmlElement
private List<Stock> stock;
}
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Stocks readStocks() {
final Stocks entity; ///
return Response.ok(entity).build();
}
According to 4.2.4 Standard Entity Providers (JSR-339), List
is not on the list of mandatory prepackaged MessageBody(Reader|Writer)
.
Is List<T>
standardized? or Which way is the most portable one?
It's not really a problem with
List
. The MBWs for both JSON and XML generally always return true forisWritable
. That's how they are able to handle all types you throw are them. What is has to do with is type erasure. The purpose of theGenericEntity
is that is caches the generic type parameter, which allows the MBW to know what type to marshal as.Note that
GenericEntity
is generally use when returningResponse
. Imagine this caseBecause of type erasure, there's just no way for MBW to know the type, by the time the entity gets to it. With some provider it doesn't matter. For example with Jackson it generally doesn't need to know the type, as it just introspects properties for serialization. But with MOXy/JAXB, it inherently needs to know the class. That's where the
GenericEntity
comes to play.