2016-06-23 54 views
10

È possibile avere unmarshall di Jackson ObjectMapper solo da un nodo specifico (e 'giù') in un albero JSON?Utilizzo di Jackson per mappare l'oggetto da un nodo specifico nell'albero JSON

Il caso d'uso è un formato di documento estensibile. Voglio camminare sull'albero e quindi pubblicare il percorso corrente su un set estensibile di plugin, per vedere se l'utente sta usando e plugin che sanno cosa fare con quella parte del documento.

Mi piacerebbe che gli autori di plugin non dovessero occuparsi dei dettagli di basso livello di JsonNode o dell'API di streaming; invece, basta passare qualche contesto e uno specifico JsonNode, e quindi essere in grado di usare l'adorabile e conveniente ObjectMapper per rendere unmarshall un'istanza della loro classe, considerando il nodo passato come radice dell'albero.

+1

Suoni esattamente come questo: http://martinfowler.com/articles/refactoring-document-load.html#CreatingObjectsDeepInTheDocumentStructure –

risposta

13

Si consideri il seguente JSON:

{ 
    "firstName": "John", 
    "lastName": "Doe", 
    "address": { 
    "street": "21 2nd Street", 
    "city": "New York", 
    "postalCode": "10021-3100", 
    "coordinates": { 
     "latitude": 40.7250387, 
     "longitude": -73.9932568 
    } 
    } 
} 

e considerare che si desidera analizzare il nodo coordinates nella seguente classe Java:

public class Coordinates { 

    private Double latitude; 

    private Double longitude; 

    // Default constructor, getters and setters omitted 
} 

Per farlo, analizzare l'intero JSON in un JsonNode con ObjectMapper:

String json = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"address\":{\"street\":" 
      + "\"21 2nd Street\",\"city\":\"New York\",\"postalCode\":\"10021-3100\"," 
      + "\"coordinates\":{\"latitude\":40.7250387,\"longitude\":-73.9932568}}}"; 

ObjectMapper mapper = new ObjectMapper(); 
JsonNode node = mapper.readTree(json); 

Quindi utilizzare JSON Pointer per interrogare il nodo coordinates e utilizzare ObjectMapper di analizzarlo nella classe Coordinates:

JsonNode coordinatesNode = node.at("/address/coordinates"); 
Coordinates coordinates = mapper.treeToValue(coordinatesNode, Coordinates.class); 

JSON Pointer è un linguaggio di percorso per attraversare JSON. Per maggiori dettagli, controllare lo RFC 6901. È disponibile in Jackson dalla versione 2.3.

+1

Questo è esattamente quello che cercavo! Assegnerò il premio una volta che avrò avuto la possibilità di implementarlo. –

+0

Direi che 'node.get (" address ")' è più semplice/più efficace per questo caso. – shmosel

+1

@shmosel Ovviamente lo è. Ma il punto qui è il percorso JSON che può essere usato per interrogare un nodo. Il JSON che ho fornito come esempio è davvero semplice e non possiamo vedere i vantaggi dell'utilizzo di JSON Path. –