2010-12-15 31 views
15

Estoy tratando de deserializar/asignar el JSON siguiente a List<Bill> objeto java utilizando Jackson json library. (Esto JSON se generó por Jackson, Iam omitiendo esa pieza por razones de brevedad)Jackson JSON + Java Generics

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

Aquí es mi método de conversión:

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()); 
} 

La entidad Bill es a continuación:

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

y yo consiga este error:

**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) 

Aquí está mi controlador de Spring3 simplificado que devuelve el i/p JSON (con Jackson mapeo configurado como vista predeterminada):

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

supongo que me estoy perdiendo algo obvio .. pero no está seguro de lo que es .. ¿Ideas ?

+0

No está diciendo que para asignar el atributo 'facturas' a la Lista de billLst. Nunca he hecho esto directamente (Spring 3.0 lo hace automágicamente), pero esperaría ver una referencia al atributo 'facturas'. – sioked

+0

Sí, eso fue un error tipográfico de mi parte: actualicé mi publicación. Gracias. Pero el problema todavía existe. – Ravi

Respuesta

20

El problema no radica en su código, sino en su entrada de ejemplo. Lo que realmente intentas deserializar es un objeto con un campo llamado "facturas", ¡no una lista! Lo que se debe utilizar como entrada es:

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

Esta es una matriz de objetos, que se convierte en una lista.

+0

ahh .. Gracias por el puntero. Estoy usando spring3 + Jackson Mapper y el json i/p que utilicé fue devuelto por el controlador. – Ravi

+2

Así que necesito convertir {"facturas": [{"cantidad": "13", "factura_ID": "billid3"}]} a [{"factura_id": "billid3", "cantidad": "13"} ] en mi lado del cliente. Estoy buscando el método de envoltura de Jackson que me permita hacerlo sin ningún código personalizado. – Ravi

+0

Ah, no tengo experiencia con Spring + Jackson, así que no puedo ofrecer más información. ¡Buena suerte con eso! –

3

Intente utilizar ObjectWriter en lugar de ObjectMapper

Writer writer=new StringWriter(); 

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

estoy usando Jackson 1.9.2