2016-02-04 21 views
5

Sto provando a consumare un servizio che mi dà un'entità con un campo che è un array.Jackson deserializzare un singolo elemento nella lista

{ 
    "id": "23233", 
    "items": [ 
    { 
     "name": "item 1" 
    }, 
    { 
     "name": "item 2" 
    } 
    ] 
} 

Ma quando l'array contiene un singolo elemento, l'oggetto stesso viene restituito, invece di una matrice di un elemento.

{ 
    "id": "43567", 
    "items": { 
     "name": "item only" 
    } 
} 

In questo caso, Jackson non riesce a convertire il mio oggetto Java.

public class ResponseItem { 

    private String id; 
    private List<Item> items; 

    //Getters and setters... 
} 

C'è una soluzione semplice per questo?

+0

Sembra un comportamento piuttosto strano per quel servizio. Qualche possibilità di dire al fornitore di risolverlo? – Thomas

+0

@Thomas Sfortunatamente no. È un grande fornitore SaaS con centinaia di utenti e io sono solo uno di loro. – WinterN

risposta

-2

Sono abbastanza Gson in grado di farlo senza intoppi. Spero che qualcuno possa aiutarti con Jackson se sei bloccato con esso.

(esempio: https://stackoverflow.com/a/18547661/1638595)

EDIT: Eh, mi dispiace voleva dire: "si spera che qualcuno ti può aiutare ..." invece di "non può". Apparso maleducato.

1

Per risolvere questo problema è possibile utilizzare un JsonDeserializer personalizzato.

E.g.

class CustomDeserializer extends JsonDeserializer<List<Item>> { 

    @Override 
    public List<Item> deserialize(JsonParser jsonParser, DeserializationContext context) 
      throws IOException, JsonProcessingException { 

     JsonNode node = jsonParser.readValueAsTree(); 

     List<Item> items = new ArrayList<>(); 
     ObjectMapper mapper = new ObjectMapper(); 

     if (node.size() == 1) { 
      Item item = mapper.readValue(node.toString(), Item.class); 
      items.add(item); 

     } else { 
      for (int i = 0; i < node.size(); i++) { 
       Item item = mapper.readValue(node.get(i).toString(), Item.class); 
       items.add(item); 
      } 
     } 

     return items; 
    } 

} 

bisogna dire a Jackson di usare questo a de-serializzare items, come:

@JsonDeserialize(using = CustomDeserializer.class) 
private List<Item> items; 

Dopo che funzionerà. Felice codifica :)

+0

questo è male. non funzionerà con strutture profonde in cui potresti desiderare valori singoli come array su più livelli. Utilizzo di un mapper separato per deserializzare l'intero ramo List nel modo predefinito. Il mapper aggiuntivo viene istanziato con la deserializzazione di ogni elenco. –

Problemi correlati