2010-12-15 22 views
15

Próbuję deserializować/odwzorować poniższy JSON na List<Bill> Obiekt java przy użyciu Jackson json library. (Ten json została wygenerowana przez Jackson, Iam pomijając ten kawałek dla zwięzłość)Jackson JSON + Java Generics

{"bills":[{"amount":"13","billId":"billid3"}]} 

Oto moja metoda konwersji:

private static void convert(){ 
    String jsonBill = "{\"bills\":[{\"amount\":\"13\",\"billId\":\"billid3\"}]}"; 

    ObjectMapper mapper = new ObjectMapper(); 
    List<Bill> bills = null; 
    try { 
     bills = mapper.readValue(jsonBill, new TypeReference<List<Bill>>() { }); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    System.out.println("bills = " + bills.size()); 
} 

Podmiot Bill jest poniżej:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS) 
public class Bill { 
    private String amount; 
    private String billId; 

    public String getBillId() { 
     return billId; 
    } 
    public void setBillId(String billId) { 
     this.billId = billId; 
    } 
    public String getAmount() { 
     return amount; 
    } 
    public void setAmount(String amount) { 
     this.amount = amount; 
    } 
} 

i ja ten błąd:

**org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.List out of START_OBJECT token 
at [Source: [email protected]; line: 1, column: 1]** 
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:160) 
at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:194) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:103) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:93) 
at org.codehaus.jackson.map.deser.CollectionDeserializer.deserialize(CollectionDeserializer.java:25) 
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1980) 
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1278) 

Oto moje uproszczone kontroler spring3 która zwraca json I/P (z mapowania Jackson skonfigurowany jako domyślny widok):

@ModelAttribute("bills") 
@RequestMapping(value = "/", method = RequestMethod.GET) 
public List<Bill> fetchBills() throws IOException { 
    Bill bill = new Bill(); 
    bill.setAmount("13"); 
    bill.setBillId("billid3"); 

    List<Bill> bills = new ArrayList<Bill>(); 
    bills.add(bill); 
    return bills; 
} 

Myślę, że jestem brakuje czegoś oczywiste .. ale nie wiem co to jest .. Jakieś pomysły ?

+0

Nie mówisz go zmapować atrybut „rachunki” do listy billLst. Nigdy nie robiłem tego bezpośrednio (wiosna 3.0 robi to automagicznie), ale spodziewałbym się zobaczyć odniesienie do atrybutu "rachunki". – sioked

+0

Tak, to był literówka z mojej strony - zaktualizowałem mój post. Dzięki. Ale problem nadal istnieje .. – Ravi

Odpowiedz

20

Problem nie leży w kodzie, ale w przykładowym wprowadzeniu. To, co faktycznie próbujesz deserializować, to obiekt z polem o nazwie "rachunki", a nie lista! To, co powinieneś używać jako wejścia, to:

[{"billId":"billid3","amount":"13"}] 

Jest to tablica obiektów, które są konwertowane na listę.

+0

ahh .. Dzięki za wskaźnik. Używam spring3 + Jackson Mapper, a json i/p I został zwrócony przez kontroler. – Ravi

+2

Muszę więc przekonwertować {"rachunki": [{"kwota": "13", "billId": "billid3"}]} na [{"billId": "billid3", "amount": "13"} ] po mojej stronie klienta. Szukam metody opakowania Jacksona, która pozwoli mi to zrobić bez żadnego niestandardowego kodu. – Ravi

+0

Ah, nie mam doświadczenia z Spring + Jackson, więc nie mogę zaoferować więcej wglądu. Powodzenia z tym! –

3

Spróbuj użyć ObjectWriter zamiast ObjectMapper

Writer writer=new StringWriter(); 

     ObjectWriter oWriter=om.writerWithType(new TypeReference<List<Bill>>() { 
     }); 
     oWriter.writeValue(writer, result); 

używam Jacksona 1.9.2