2013-03-24 22 views
9

Buduję usługę WWW RESTful w Javie przy użyciu oprogramowania Jersey 1.11 i mam problemy z implementacją metody, która pobiera listę obiektów JSON-ised. Metoda pojedynczej instancji działa dobrze.Jersey, jak wyświetlić listę obiektów JSON?

Błąd pojawia się:

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

Moja metoda podpis wygląda następująco:

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

JSON przesyłam we wnioskach jest tablicą MyEntity obiektów JSON:

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

Podobne pytania zadawano wcześniej, a jedno proste rd sugestia polegała na zmianie rodzaju używanego nośnika na tekst i dekompresji numeru JSON manually, ale wolałbym czystsze rozwiązanie.

Czy JSON, który wysyłam, jest ważny w tym kontekście, czy też potrzebuję najwyższego poziomu {}, tj. Jednostki opakowania? Wydawałoby się to również trochę nienaturalne.

Dziękuję

/David

+0

zamieścić samą odpowiedź na poniższy link .... http://stackoverflow.com/questions/13242414/passing-a-list-of-objects-into-an-mvc-controller-method- using-jquery-ajax/43582662 # 43582662 –

Odpowiedz

6

myślę PathParam a także Param, które powinny unmarshalled przez Jersey (JAX-RS) nie jest możliwe. Proszę usunąć parametr PathParam.

A jeśli potrzebujesz drugiego parametru więc stworzyć nową klasę jak ten

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

a także zmodyfikować Methode:

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

Twój JSON powinien wyglądać następująco:

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

To jest prawidłowy JSON dla tablicy:

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

(patrz here na przykład)

Nie trzeba wysyłać wiadomości tekstowe można wysyłać go jako JSON. Również twój MyEntity powinien mieć na sobie @XmlRootElement (patrz np. here, sekcja 5.2).

Nie potrzebujesz PathParam w swoich argumentach, jest dostępna, gdy żądanie zostanie wysłane, jeśli pozostawisz @Path("/some-path/{someParam}") w swoim podpisie metody.

3

OK, więc na koniec rozwiązałem to za pomocą prostej klasy opakowania, aby wygenerować { items : [{ <myEnityInstanceJson1> }, { <myEnityInstanceJson2> }, ... ]}. Chyba nie ma sposobu, aby mieć ogólny wrapper ale teraz to zrobi:

@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

Problemem jest rodzajowy lista typ, który nie jest dostępny w czasie wykonywania ze względu na rodzaj skasowaniu, więc Jersey przyzwyczajenie wiedzieć, jaki rodzaj POJO do unmarshal.

myślę najprostsze rozwiązanie (które znam prace, przynajmniej podczas korzystania Jackson w swojej MessageBodyReader) w tym przypadku byłoby po prostu użyć zwykłej tablicy Java zamiast listy, więc podpis metoda staje:

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

I tak, łączenie @PathParam i parametru body/used/unmarshalled body powinno być w porządku.

0

Działa klasa owijarki. MyEntity[] myEnts nie działa.

To jest to, co zrobiłem i zadziałało.

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

Użyj ObjectMapper, aby przekonwertować na listę obiektów.

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