在 jax-rs 中返回列表作为响应的最便携(或标准)方式是什么?
What is the most portable (or standard) way of returning a list as a response in jax-rs?
好吧,任何人都可以说这个问题已经被提出并得到了回答。没关系我也找到了。
- 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>>
我对使用 List<T>
进行响应的方式并不感到困惑,只是不相信其可移植性。
假设我有一个很好注释的实体,看起来像这样。
@XmlRootElement
public class Stock {
@XmlAttribute
private Long id;
}
列表<股票>
什么时候这样做,
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Stock> readStocks() {
final List<Stock> list = getStocks();
return list;
}
据了解,GlassFish 和 WileFly 可以正常工作。
<stocks> <!-- automatic plural? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</stocks>
<collection> <!-- fixed? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</collection>
和JSON,(我认为可能因提供商而异)
[
{
"id": 1
},
{
"id": 2
}
]
通用实体<列表<股票>>
有时我会在容器找不到 MessageBodyWriter
时遇到问题。所以我喜欢这个。
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public GenericEntity<List<T>> readStocks() {
return new GenericEntity<List<Stock>>(getStocks()) {};
}
或
@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();
}
根据 4.2.4 Standard Entity Providers (JSR-339),List
不在强制预打包列表中 MessageBody(Reader|Writer)
。
List<T>
是否标准化?或者哪种方式最便携?
List
并不是真正的问题。 JSON 和 XML 的 MBW 对于 isWritable
通常总是 return 正确。这就是他们能够处理您抛出的所有类型的方式。 与有关的是类型擦除。 GenericEntity
的目的是缓存泛型类型参数,这允许 MBW 知道要编组的类型。
注意 GenericEntity
通常在 returning Response
时使用。想象一下这种情况
public Response get() {
List<Somthing> l = service.get();
return Response.ok(l).build();
}
由于类型擦除,MBW 无法在实体到达类型时知道类型。对于一些提供者来说,这并不重要。例如对于 Jackson,它通常不需要知道类型,因为它只是内省序列化的属性。但是对于 MOXy/JAXB,它本质上需要知道 class。这就是 GenericEntity
发挥作用的地方。
Normally type erasure removes generic type information such that a Response
instance that contains, e.g., an entity of type List<String>
appears to contain a raw List<?>
at runtime. When the generic type is required to select a suitable MessageBodyWriter
, this class may be used to wrap the entity and capture its generic type.
...
List<String> list = new ArrayList<String>();
GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {};
Response response = Response.ok(entity).build();
好吧,任何人都可以说这个问题已经被提出并得到了回答。没关系我也找到了。
- 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>>
我对使用 List<T>
进行响应的方式并不感到困惑,只是不相信其可移植性。
假设我有一个很好注释的实体,看起来像这样。
@XmlRootElement
public class Stock {
@XmlAttribute
private Long id;
}
列表<股票>
什么时候这样做,
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Stock> readStocks() {
final List<Stock> list = getStocks();
return list;
}
据了解,GlassFish 和 WileFly 可以正常工作。
<stocks> <!-- automatic plural? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</stocks>
<collection> <!-- fixed? -->
<stock xmlns="http://...">
</stock>\
<stock xmlns="http://...">
</stock>
</collection>
和JSON,(我认为可能因提供商而异)
[
{
"id": 1
},
{
"id": 2
}
]
通用实体<列表<股票>>
有时我会在容器找不到 MessageBodyWriter
时遇到问题。所以我喜欢这个。
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public GenericEntity<List<T>> readStocks() {
return new GenericEntity<List<Stock>>(getStocks()) {};
}
或
@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();
}
根据 4.2.4 Standard Entity Providers (JSR-339),List
不在强制预打包列表中 MessageBody(Reader|Writer)
。
List<T>
是否标准化?或者哪种方式最便携?
List
并不是真正的问题。 JSON 和 XML 的 MBW 对于 isWritable
通常总是 return 正确。这就是他们能够处理您抛出的所有类型的方式。 与有关的是类型擦除。 GenericEntity
的目的是缓存泛型类型参数,这允许 MBW 知道要编组的类型。
注意 GenericEntity
通常在 returning Response
时使用。想象一下这种情况
public Response get() {
List<Somthing> l = service.get();
return Response.ok(l).build();
}
由于类型擦除,MBW 无法在实体到达类型时知道类型。对于一些提供者来说,这并不重要。例如对于 Jackson,它通常不需要知道类型,因为它只是内省序列化的属性。但是对于 MOXy/JAXB,它本质上需要知道 class。这就是 GenericEntity
发挥作用的地方。
Normally type erasure removes generic type information such that a
Response
instance that contains, e.g., an entity of typeList<String>
appears to contain a rawList<?>
at runtime. When the generic type is required to select a suitableMessageBodyWriter
, this class may be used to wrap the entity and capture its generic type....
List<String> list = new ArrayList<String>(); GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {}; Response response = Response.ok(entity).build();