泽西岛,如何POST一个JSON对象列表?

我正在使用Jersey 1.11在Java中构建RESTful Web服务,并且在实现消耗JSON-ised实体列表的方法时遇到问题。 单实例方法工作正常。

我得到的错误是:

Status 400 - Bad Request. The request sent by the client was syntactically incorrect. 

我的方法签名如下所示:

 @POST @Path("/some-path/{someParam}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public String createBatch(List myEnts, @PathParam("someParam") String someParam) { ... } 

我在请求中发送的JSON是MyEntity JSON对象的数组:

 [{"field1" : value1, "field2" : value2}, {"field1" : value3, "field2" : value4}, ...] 

之前已经提出了类似的问题,一个直接的建议是将消费的媒体类型更改为文本并手动反序列化JSON,但我更喜欢更清晰的解决方案。

我发送的JSON在这种情况下是否有效,或者我是否需要顶级{}即包装器实体? 这似乎有点不自然。

谢谢,

/大卫

我认为PathParam以及一个应该由Jersey(JAX-RS)解组的Param是不可能的。 请尝试删除PathParam参数。

如果你需要第二个参数,那么创建一个这样的新类

 @XmlRootElement(name = "example") public class Example { @XmlElement(name = "param") private String param; @XmlElement(name = "entities") private List entities; } 

并修改您的Methode:

 @POST @Path("/some-path") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public String createBatch(Example example) { ... } 

你的JSON应该是这样的:

 { "param":"someParam", "entities":[ {"field1" : value1, "field2" : value2}, {"field1" : value3, "field2" : value4}, ...] } 

好的,所以最后我用一个简单的包装类来解决这个问题,以便生成{ items : [{ }, { }, ... ]} 。 我想有一种方法可以使用通用包装器,但现在这样做:

 @XmlRootElement public class MyEntityWrapper implements Serializable { private static final long serialVersionUID = 1L; private List items; public MyEntityWrapper() { this.items = new ArrayList(); } public MyEntityWrapper(List items) { this.items = items; } public List getItems() { return items; } public void setItems(List items) { this.items = items; } } 

问题是通用列表类型,由于类型擦除而无法在运行时使用,因此Jersey不知道要解组什么类型的POJO。

我认为在这种情况下,最简单的解决方案(我知道可行,至少在您的MessageBodyReader使用Jackson)将只使用普通的Java数组而不是List,因此方法签名变为:

 public String createBatch(@PathParam("someParam") String someParam, MyEntity[] myEnts) 

是的,组合@PathParam和消耗/解组的body参数应该没问题。

包装类工作。 MyEntity[] myEnts不起作用。

这就是我所做的,它的工作原理。

 public String createBatch(@PathParam("someParam") String someParam, String content) 

使用ObjectMapper转换为对象列表。

 List entities = om.readValue(content, new TypeReference>(){}). 

这是一个有效的数组JSON:

 {"elements": [ {"field1" : value1, "field2" : value2}, {"field1" : value3, "field2" : value4}, ...] }; 

(见这里的例子)

您不需要发送文本,可以将其作为JSON发送。 你的MyEntity应该有@XmlRootElement (参见这里 ,5.2节的例子)。

您的参数中不需要PathParam ,如果您在方法签名中保留@Path("/some-path/{someParam}") ,则在发布请求时可以使用@Path("/some-path/{someParam}")