2013-03-24 3 views
9

Я создаю веб-сервис RESTful на Java, используя Jersey 1.11, и у меня возникли проблемы с внедрением метода, который использует список объектов JSON. Метод одиночных экземпляров отлично работает.Джерси, как POST список объектов JSON?

Ошибки я получаю:

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<MyEntity> myEnts, @PathParam("someParam") String someParam) 
{ 
    ... 
} 

JSON Я посылаю в запросах является массивом MyEntity объектов JSON:

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

Аналогичные вопросы задавали раньше и один прямой forwa Было предложено изменить тип потребляемой среды на текст и де-сериализовать JSON manually, но я предпочел бы более чистое решение.

Является ли JSON отправкой даже в этом контексте или мне нужен верхний уровень {} i.e объект-оболочка? Это также показалось бы немного неприродным.

Спасибо,

/David

+0

я отправляю тот же ответ на следующую ссылку .... http://stackoverflow.com/questions/13242414/passing-a-list-of-objects-into-an-mvc-controller-method- используя-JQuery-Аякс/43582662 # 43582662 –

ответ

6

Я думаю PathParam, а также Парам, которые должны unmarshalled на Джерси (JAX-RS) не представляется возможным. Попробуйте удалить параметр PathParam.

И если вам нужен второй параметр таким образом, создать новый класс, как этот

@XmlRootElement(name = "example") 
public class Example { 
    @XmlElement(name = "param") 
    private String param; 
    @XmlElement(name = "entities") 
    private List<MyEntity> 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}, ...] 
} 
0

Это действительный JSON для массива:

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

(см here для примера)

Вам не нужно отправить текст, вы можете отправить его в формате JSON. Также ваш MyEntity должен иметь на нем @XmlRootElement (см. Пример here, раздел 5.2).

В ваших аргументах не требуется PathParam, someParam доступен, когда запрос отправлен, если вы оставите @Path("/some-path/{someParam}") в вашей сигнатуре метода.

3

Хорошо, поэтому в конце я решил это, используя простой класс-оболочку, чтобы сгенерировать { items : [{ <myEnityInstanceJson1> }, { <myEnityInstanceJson2> }, ... ]}. Я предполагаю, что есть способ иметь общий wrapper но сейчас это будет делать:

@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

Проблема в том, общий тип списка, который не доступен во время выполнения в зависимости от типа стирания, поэтому Джерси обыкновение знать, какие из POJO для развязывания.

Я думаю, что самое простое решение (которое я знаю, работает, по крайней мере при использовании Джексона в вашем MessageBodyReader) в этом случае было бы просто использовать обычный Java массив вместо списка, поэтому метод подписи становится:

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

И да, комбинация @PathParam и параметр потребляемого/немаршаллируемого тела должны быть точными.

0

Wrapper класс работает. MyEntity[] myEnts не работает.

Это то, что я сделал, и это сработало.

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

Использование ObjectMapper преобразовать в список объектов.

List<MyEntity> entities = om.readValue(content, 
             new TypeReference<List<MyEntity>>(){}). 
Смежные вопросы