【问题标题】:Jersey can produce List<T> but cannot Response.ok(List<T>).build()?Jersey 可以生成 List<T> 但不能 Response.ok(List<T>).build()?
【发布时间】:2022-01-17 22:58:31
【问题描述】:

Jersey 1.6 可以生产:

@Path("/stock")
public class StockResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Stock> get() {
        Stock stock = new Stock();
        stock.setQuantity(3);
        return Lists.newArrayList(stock);
    }
}

但不能这样做:

@Path("/stock")
public class StockResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response get() {
        Stock stock = new Stock();
        stock.setQuantity(3);
        return Response.ok(Lists.newArrayList(stock)).build();
    }
}

给出错误:A message body writer for Java class java.util.ArrayList, and Java type class java.util.ArrayList, and MIME media type application/json was not found

这会阻止使用 HTTP 状态代码和标头。

【问题讨论】:

标签: java json jaxb jersey generic-list


【解决方案1】:

可以通过以下方式在响应中嵌入List&lt;T&gt;

@Path("/stock")
public class StockResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response get() {
        Stock stock = new Stock();
        stock.setQuantity(3);

        GenericEntity<List<Stock>> entity = 
            new GenericEntity<List<Stock>>(Lists.newArrayList(stock)) {};
        return Response.ok(entity).build();
    }
}

客户端必须使用以下行来获取List&lt;T&gt;

public List<Stock> getStockList() {
    WebResource resource = Client.create().resource(server.uri());
    ClientResponse clientResponse =
        resource.path("stock")
        .type(MediaType.APPLICATION_JSON)
        .get(ClientResponse.class);
    return clientResponse.getEntity(new GenericType<List<Stock>>() {
    });
}

【讨论】:

  • 这个解决方案有个小问题就是你需要番石榴
  • @Necronet:上面提供的服务器端解决方案不需要 Guava,对吗?
  • @Nitax Lists.newArrayList 来自番石榴。您可以在纯 Java 中轻松地将其替换为 new ArrayListadd
  • 啊,是的,我错过了。无论哪种方式都很好。
【解决方案2】:

出于某种原因,我无法修复 GenericType。然而,由于类型擦除是为集合而不是数组完成的,所以这很有效。

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public Response getEvents(){
        List<Event> events = eventService.getAll();
        return Response.ok(events.toArray(new Event[events.size()])).build();
    }

【讨论】:

    【解决方案3】:

    我对使用 AsyncResponse 的方法的解决方案

    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public void list(@Suspended
            final AsyncResponse asyncResponse) {
        asyncResponse.setTimeout(10, TimeUnit.SECONDS);
        executorService.submit(() -> {
            List<Product> res = super.listProducts();
            Product[] arr = res.toArray(new Product[res.size()]);
            asyncResponse.resume(arr);
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 2013-08-03
      • 2019-05-20
      • 2021-11-26
      • 2011-06-25
      相关资源
      最近更新 更多