2010-12-15 59 views
15

Je suis en train de désérialiser/mapper le JSON ci-dessous à List<Bill> objet java en utilisant Jackson json library. (Ce JSON a été générée par jackson, Iam omettant ce morceau par souci de concision)Jackson JSON + Java Génériques

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

Voici ma méthode de conversion:

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

L'entité Bill est ci-dessous:

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

et je obtenir cette erreur:

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

Voici mon contrôleur de spring3 simplifié qui renvoie le JSON i/p (avec cartographie Jackson configuré comme vue par défaut):

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

Je suppose que je manque quelque chose d'évident .. mais pas sûr de ce qu'il est .. Toutes les idées ?

+0

Vous n'êtes pas dire pour cartographier les attributs « factures » à la liste billLst. Je n'ai jamais fait cela directement (Spring 3.0 le fait automagiquement), mais je m'attendrais à voir une référence à l'attribut 'bills'. – sioked

+0

Oui c'était une faute de frappe de ma part - mis à jour mon post. Merci. Mais le problème existe toujours .. – Ravi

Répondre

20

Le problème ne réside pas dans votre code, mais dans votre exemple d'entrée. Ce que vous essayez de désérialiser est un objet avec un champ nommé "factures", pas une liste! Ce que vous devez utiliser comme entrée est:

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

Ceci est un tableau d'objets, qui est converti en liste.

+0

ahh .. Merci pour le pointeur. J'utilise spring3 + Jackson Mapper et le json i/p que j'ai utilisé a été retourné par le contrôleur. – Ravi

+2

J'ai donc besoin de convertir {"bills": [{"amount": "13", "billId": "billid3"}]} en [{"billId": "billid3", "montant": "13"} ] du côté de mon client. Je cherche la méthode de wrapper de Jackson qui me laisse faire cela sans aucun code personnalisé. – Ravi

+0

Ah, je n'ai aucune expérience avec Spring + Jackson, donc je ne peux pas offrir plus de perspicacité. Bonne chance avec ça! –

3

Essayez d'utiliser ObjectWriter au lieu de ObjectMapper

Writer writer=new StringWriter(); 

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

J'utilise jackson 1.9.2