简体   繁体   English

Jersey,如何POST一个JSON对象列表?

[英]Jersey, how to POST a list of JSON objects?

I am building a RESTful web-service in Java using Jersey 1.11, and have problems implementing a method which consumes a list of JSON-ised entities. 我正在使用Jersey 1.11在Java中构建RESTful Web服务,并且在实现消耗JSON-ised实体列表的方法时遇到问题。 The single instance method works fine. 单实例方法工作正常。

The error I get is: 我得到的错误是:

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

My method signature looks like this: 我的方法签名如下所示:

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

The JSON I am sending in the requests is an array of MyEntity JSON objects: 我在请求中发送的JSON是MyEntity JSON对象的数组:

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

Similar questions have been asked before and one straight forward suggestion was to change the consumed media type to text and de-serialize the JSON manually but I'd prefer a cleaner solution. 之前已经提出了类似的问题,一个直接的建议是将消费的媒体类型更改为文本并手动反序列化JSON,但我更喜欢更清洁的解决方案。

Is the JSON I am sending even valid in this context or do I need a top-level {} ie a wrapper entity? 我发送的JSON在这种情况下是否有效,或者我是否需要顶层{}即包装器实体? This would also seem a bit un-natural. 这似乎有点不自然。

Thank you, 谢谢,

/David /大卫

I think PathParam and also a Param which should unmarshalled by Jersey(JAX-RS) is not possible. 我认为PathParam以及一个应该由Jersey(JAX-RS)解组的Param是不可能的。 Please try to remove the PathParam Parameter. 请尝试删除PathParam参数。

And if you need the second Parameter so create a new class like this 如果你需要第二个参数,那么创建一个这样的新类

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

and also modify your Methode : 并修改您的Methode:

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

your JSON Should look like this: 你的JSON应该是这样的:

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

Ok, so in the end I solved this using a simple wrapper class in order to generate { items : [{ <myEnityInstanceJson1> }, { <myEnityInstanceJson2> }, ... ]} . 好的,所以最后我用一个简单的包装类来解决这个问题,以生成{ items : [{ <myEnityInstanceJson1> }, { <myEnityInstanceJson2> }, ... ]} I guess there is a way to have a generic wrapper but for now this will do: 我想有一种方法可以使用通用包装器,但现在这样做:

@XmlRootElement
public class MyEntityWrapper implements Serializable {

    private static final long serialVersionUID = 1L;

    private List<MyEntity> items;

    public MyEntityWrapper() {
        this.items = new ArrayList<MyEntity>();
    }

    public MyEntityWrapper(List<MyEntity> items) {
        this.items = items;
    }

    public List<MyEntity> getItems() {
        return items;
    }

    public void setItems(List<MyEntity> items) {
        this.items = items;
    }
}

The problem is the generic list type, which is not available at runtime due to type erasure, so Jersey wont know what kind of POJOs to unmarshal. 问题是通用列表类型,由于类型擦除而无法在运行时使用,因此Jersey不知道要解组什么类型的POJO。

I think the simplest solution (which I know works, at least when using Jackson in your MessageBodyReader ) in this case would be to just use a normal Java array instead of the List, so the method signature becomes: 我认为在这种情况下,最简单的解决方案(我知道可行,至少在你的MessageBodyReader使用Jackson)将只使用普通的Java数组而不是List,因此方法签名变为:

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

And yes, combining @PathParam and a consumed/unmarshalled body parameter should be fine. 是的,组合@PathParam和消耗/解组的body参数应该没问题。

Wrapper class works. 包装类工作。 MyEntity[] myEnts doesn't work. MyEntity[] myEnts不起作用。

This is what I did and it worked. 这就是我所做的并且有效。

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

Use ObjectMapper to convert to List of objects. 使用ObjectMapper转换为对象列表。

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

This is valid JSON for an array: 这是数组的有效JSON:

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

(see here for an example) (见这里的例子)

You don't need to send text, you can send it as JSON. 您不需要发送文本,可以将其作为JSON发送。 Also your MyEntity should have @XmlRootElement on it (see here , section 5.2 for an example). 你的MyEntity应该有@XmlRootElement (参见这里 ,5.2节的例子)。

You don't need PathParam in your arguments, someParam is available when the request is posted if you leave the @Path("/some-path/{someParam}") in your method signature . 你不需要PathParam在你的论点, someParam当你离开的请求,发布可@Path("/some-path/{someParam}")在你的方法签名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM