2013-07-29 15 views
7

Ich habe eine JSON-Zeichenfolge, die aus folgendem Format sein:Jackson - Deserialize verschachtelt JSON

{ 
    "response": { 
    "execution_status": "ready", 
    "report": { 
     "cache_hit": true, 
     "created_on": "2013-07-29 08:42:42", 
     "fact_cache_error": null, 
     "fact_cache_hit": true, 
     "header_info": null, 
     "name": null, 
     "report_size": "5871", 
     "row_count": "33", 
     "url": "report-download?id=278641c223bc4e4d63df9e83d8fcb4e6" 
    }, 
    "status": "OK" 
    } 
} 

Die Antwort Teil des JSON ist für eine Reihe von Antworttypen gemeinsam. Der Berichtsteil dieses JSON gilt nur für diese Antwort. So hatte ich eine Antwort-Klasse erstellt, wie unten mit Getter und Setter gezeigt (nicht die Getter und Setter hier der Kürze halber enthalten):

@JsonRootName(value = "response") 
public class Response implements Serializable { 

    private static final long serialVersionUID = -2597493920293381637L; 

    @JsonProperty(value = "error") 
    private String error; 
    @JsonProperty(value = "error_code") 
    private String errorCode; 
    @JsonProperty(value = "error_id") 
    private String errorId; 
    @JsonProperty(value = "error_description") 
    private String errorDescription; 
    @JsonProperty(value = "method") 
    private String method; 
    @JsonProperty(value = "service") 
    private String service; 
    @JsonProperty(value = "status") 
    private String status; 
    @JsonProperty(value = "execution_status") 
    private String executionStatus; 
} 

Und dann habe ich eine Berichtsklasse mit den Feldern im Berichtselement als unten. Die ReportResponse-Klasse von der Response-Klasse erweitern wird (wieder die Getter und Setter sind der Kürze halber nicht im Lieferumfang enthalten):

public class ReportResponse extends Response { 

    private static final long serialVersionUID = 4950819240030644407L; 

    @JsonProperty(value = "cache_hit") 
    private Boolean cacheHit; 
    @JsonProperty(value = "created_on") 
    private Timestamp createdOn; 
    @JsonProperty(value = "fact_cache_error") 
    private String factCacheError; 
    @JsonProperty(value = "fact_cache_hit") 
    private Boolean factCacheHit; 
    @JsonProperty(value = "header_info") 
    private String headerInfo; 
    @JsonProperty(value = "json_request") 
    private String jsonRequest; 
    @JsonProperty(value = "name") 
    private String name; 
    @JsonProperty(value = "report_size") 
    private Integer reportSize; 
    @JsonProperty(value = "row_count") 
    private Integer rowCount; 
    @JsonProperty(value = "url") 
    private String url; 
} 

Nun, wenn ich die ObjectMapper verwenden, um das ReportResponse Objekt abzubilden, erhalte ich die folgende Fehlermeldung:

String jsonString = "{\"response\": {\"execution_status\": \"ready\", \"report\": {\"cache_hit\": true, \"created_on\": \"2013-07-29 09:53:44\", \"fact_cache_error\": null, \"fact_cache_hit\": false, \"header_info\": null, \"name\": null, \"report_size\": \"5871\", \"row_count\": \"33\", \"url\": \"report-download?id=2ff62c07fc3653b68f2073e7c1aa0517\"}, \"status\": \"OK\"}}"; 
ObjectMapper mapper = new ObjectMapper(); 
ReportResponse reportResponse = mapper.readValue(jsonString, ReportResponse.class); 

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "report" 

Ich weiß, dass ich eine separate Report-Klasse erstellen und dann in die ReportResponse mit der @ JsonProperty-Antion einbetten kann. Gibt es eine Möglichkeit, die ich vermeiden kann, und die ReportResponse-Klasse mit einer Annotation zu markieren, die es dem Element "report" im JSON zuordnen würde?

Antwort

9

Es gibt keine Anmerkung, die diesen Fall noch behandeln könnte. There is a ticket requesting this feature.

Here is a brief statement from one of the owners regarding this topic.

Zitat aus der erwähnten Aussage:

Tatu Saloranta: "… @JsonProperty does not support transformations, since the data binding is based on incremental parsing and does not have access to full tree representation. Supporting @JsonUnwrapped was non-trivial, but doable; and thus converse ("@JsonWrapped") would be doable, theoretically speaking. Just plenty of work. …"

+0

Danke nutlike. Kennen Sie eine Arbeit für dieses Szenario? Oder muss ich nur einen unnötigen Wrapper erstellen? – Anand

+0

@Anand: Ich denke, du musst mit dem unnötigen Wrapper gehen - ich kann mir zu diesem Zeitpunkt keine andere Lösung vorstellen. Vielleicht kann sich jemand anderes etwas einfallen lassen. Viel Glück! – nutlike

+2

Sie verwenden jira nicht mehr zur Problemverfolgung. Die neue Ausgabe: https://github.com/FasterXML/jackson-databind/issues/512 –

2

Ich sehe einige Probleme in Ihrem Code. Die erste Sache ist, dass Sie kein report Attribut in Ihrer Response-Klasse haben, was gemäß der von Ihnen gezeigten JSON-Struktur erforderlich ist. Zweitens müssen Sie die Getter und Setter in Ihren Bean-Klassen bereitstellen, da diese von der Jackson zum Marsh- und Unmarshalling von JSON/Objekt verwendet werden.

+0

Juned - Ich habe nicht die Getter und Setter in diesem Beitrag nicht nur der Kürze halber enthalten. Es wird viel Platz einnehmen und daher habe ich sie weggelassen. Ich weiß, dass ich ein Berichtselement für Jackson haben muss, um den JSON zu entpacken. Meine Frage war zu sehen, ob es eine Möglichkeit gibt, die ReportResponse als Berichtselement zu markieren, so dass ich keine andere Klasse erstellen muss – Anand