在jax-rs中将列表作为响应返回的最便携(或标准)方式是什么?

时间:2015-10-17 19:12:20

标签: jersey jax-rs cxf resteasy restlet

嗯,任何人都可以说这个问题已经被问到并回答了。没关系我也发现了它们。

我并没有对使用List<T>做出回应的方式感到困惑,而只是不相信可移植性。

让我们说我有一个很好的注释实体看起来像这样。

@XmlRootElement
public class Stock {

    @XmlAttribute
    private Long id;
}

<小时/> 的列表与LT;股票及GT;

什么时候这样做,

@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
    }
]

<小时/> 的 GenericEntity&LT;列表与LT;股票及GT;&GT;

有时我发现容器无法找到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标准实体提供者(JSR-339),List不在强制性预先包装MessageBody(Reader|Writer)列表中。

List<T>标准化了吗?或哪种方式最便携?

1 个答案:

答案 0 :(得分:2)

List并不是真正的问题。对于isWritable,JSON和XML的MBW通常总是返回true。这就是他们能够处理你抛出的所有类型的方式。 有什么关系才是类型擦除。 GenericEntity的目的是缓存泛型类型参数,它允许MBW知道要编组的类型。

请注意,GenericEntity通常在返回Response时使用。想象一下这个案例

public Response get() {
    List<Somthing> l = service.get();
    return Response.ok(l).build();
}

由于类型擦除,当实体到达时,MBW无法知道类型。对某些提供商而言并不重要。例如,对于Jackson,它通常不需要知道类型,因为它只是内省了序列化的属性。但是使用MOXy / JAXB,它本身就需要知道这个类。这就是GenericEntity发挥作用的地方。

  

通常,类型擦除会删除泛型类型信息,以便包含例如类型Response的实体的List<String>实例在运行时似乎包含原始List<?>。当需要泛型类型来选择合适的MessageBodyWriter时,此类可用于包装实体并捕获其泛型类型。

     

...

List<String> list = new ArrayList<String>();
GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {};
Response response = Response.ok(entity).build();