2013-03-24 49 views
9

Tôi đang xây dựng một dịch vụ web RESTful trong Java bằng cách sử dụng Jersey 1.11 và gặp sự cố khi triển khai phương thức tiêu thụ danh sách các thực thể được tạo JSON. Phương thức cá thể đơn hoạt động tốt.Jersey, cách POST một danh sách các đối tượng JSON?

Các lỗi tôi nhận được là:

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

phương pháp Chữ ký của tôi trông như thế này:

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

Các JSON Tôi gửi trong yêu cầu là một mảng của MyEntity đối tượng JSON:

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

Các câu hỏi tương tự đã được hỏi trước và một câu hỏi trực tiếp đề xuất thứ ba là thay đổi loại phương tiện truyền thông tiêu thụ thành văn bản và de-serialize các JSON manually nhưng tôi muốn có một giải pháp sạch hơn.

JSON tôi đang gửi thậm chí hợp lệ trong ngữ cảnh này hay tôi cần một thực thể bao bọc hàng đầu {}? Điều này cũng có vẻ hơi không tự nhiên.

Cảm ơn bạn,

/David

+0

tôi gửi cùng một câu trả lời về sau liên kết .... http://stackoverflow.com/questions/13242414/passing-a-list-of-objects-into-an-mvc-controller-method- sử dụng-jquery-ajax/43582662 # 43582662 –

Trả lời

6

Tôi nghĩ PathParam và cũng là một Param mà nên unmarshalled bởi Jersey (JAX-RS) là không thể. Hãy thử xóa tham số PathParam.

Và nếu bạn cần các thông số thứ hai để tạo ra một lớp mới như thế này

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

và cũng sửa đổi Methode của bạn:

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

JSON của bạn nên trông như thế này:

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

Đây là JSON hợp lệ cho một mảng:

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

(xem here cho một ví dụ)

Bạn không cần phải gửi văn bản, bạn có thể gửi nó như JSON. Ngoài ra, MyEntity của bạn phải có @XmlRootElement trên đó (xem here, mục 5.2 để biết ví dụ).

Bạn không cần PathParam trong đối số của mình, someParam khả dụng khi yêu cầu được đăng nếu bạn rời khỏi @Path("/some-path/{someParam}") trong chữ ký phương thức của mình.

3

Ok, vì vậy cuối cùng tôi đã giải quyết vấn đề này bằng cách sử dụng lớp trình bao bọc đơn giản để tạo ra { items : [{ <myEnityInstanceJson1> }, { <myEnityInstanceJson2> }, ... ]}. Tôi đoán có một cách để có một generic wrapper nhưng bây giờ điều này sẽ làm:

@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; 
    } 
} 
1

Vấn đề là các loại danh sách chung chung, mà không phải là có sẵn trong thời gian chạy do gõ tẩy xoá, vì vậy Jersey sẽ không biết loại của POJOs so sánh.

Tôi nghĩ rằng giải pháp đơn giản nhất (mà tôi biết công trình, ít nhất là khi sử dụng Jackson trong MessageBodyReader của bạn) trong trường hợp này là nên chỉ sử dụng một mảng Java bình thường thay vì danh sách, vì vậy phương pháp chữ ký trở thành:

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

Và có, kết hợp @PathParam và thông số cơ thể được tiêu thụ/không được khắc phục phải ổn.

0

Hoạt động của lớp trình bao bọc. MyEntity[] myEnts không hoạt động.

Đây là những gì tôi đã làm và nó hoạt động.

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

Sử dụng ObjectMapper để chuyển sang Danh sách đối tượng.

List<MyEntity> entities = om.readValue(content, 
             new TypeReference<List<MyEntity>>(){}). 
Các vấn đề liên quan