2016-06-06 4 views
1

Ich verarbeite eine JSON-Nachricht mit Federintegration. Die Nachricht kann im Format variieren und ich interessiere mich für ein bestimmtes Unterobjekt (genannt payload) des gesamten JSON, das ich erhalte. Ich stimme die Java-Klasse für dieses Unterobjekt mit einem anderen Feld (type) aus der empfangenen Nachricht ab, um zu wissen, wie es deserialisiert wird.ObjectToJsonTransformer in Spring 4 löst NPE mit Nullwerten

Um dies zu erreichen, konvertiere ich die Nachricht an einen java.lang.Object<int:json-to-object-transformer type="java.lang.Object" /> mit - dies wird in der Tat zu einem LinkedMap Objekt der ursprüngliche JSON konvertieren, die ich für Felder abfragen kann und Filterung und Routing innerhalb meiner Feder Integration xml durchführen - zum Beispiel:

<int:recipient-list-router input-channel="jsonInputChannel" ignore-send-failures="false" default-output-channel="fallbackChannel"> 
    <int:recipient 
    channel="validInputChannel" 
    selector-expression="payload.containsKey('type') and payload.containsKey('payload')"/> 
</int:recipient-list-router> 

In der oberhalb des payload als Map Objekt behandelt. Dann extrahieren ich das entsprechende Objekt muss ich weiter in eine bestimmte Java-Klasse verwandeln:

<int:chain input-channel="validInputChannel" output-channel="objectResolveChannel"> 
    <int:transformer expression="payload.get('payload')" /> 
    <int:object-to-json-transformer /> 
</int:chain> 

Hier bin ein NPE bin immer, wenn die Nutzlast propery der Nachricht wie {"field1": null, "field2": "something", ....} sieht

ich die hatte einen Blick Frühling 4.2.4.RELEASE Quellcode und ich kann sehen, dass ObjectToJsonTransformer Anrufe this.jsonObjectMapper.populateJavaTypes(headers, message.getPayload()); Dies, um die Methodenimplementierung in JsonObjectMapperAdapter nennt, das ist die folgende:

public void populateJavaTypes(Map<String, Object> map, Object object) { 
    map.put(JsonHeaders.TYPE_ID, object.getClass()); 
    if (object instanceof Collection && !((Collection) object).isEmpty()) { 
     map.put(JsonHeaders.CONTENT_TYPE_ID, ((Collection) object).iterator().next().getClass()); 
    } 
    if (object instanceof Map && !((Map) object).isEmpty()) { 
     map.put(JsonHeaders.CONTENT_TYPE_ID, ((Map) object).values().iterator().next().getClass()); 
     map.put(JsonHeaders.KEY_TYPE_ID, ((Map) object).keySet().iterator().next().getClass()); 
    } 
} 

Sie können sehen, dass wenn das Objekt wie eine Map-Instanz behandelt wird, der Code getClass() für das erste Element der Map-Werte verwendet, aber dies kann natürlich null lauten und daher wird die NPE ausgelöst.

Wir haben Spring 3.2.1.RELEASE zusammen mit Spring Integration 2.2.6.RELEASE verwendet und die gleiche Spring Integration XML-Konfiguration funktionierte perfekt. Soweit ich weiß, war der obige problematische Code im Frühling 3 nicht vorhanden.

Kann jemand eine schöne Abhilfe für dieses Problem vorschlagen oder einen Weg zurück zum Spring 3-Verhalten finden?

Antwort

2

Dies ist ein Fehler; Ich öffnete eine JIRA Issue.

Die einzige Behelfslösung, glaube ich, ist es, den Fehler vor Ort zu beheben (Unterklasse ObjectToJsonTransformer, doTransform() durch Entfernen der populateJavaTypes Anruf Fixierung) und ersetzen Sie die <object-to-json-transformer/> mit einem normalen <transformer/> Referenzierung Bean.

Das Füllen der Java-Header war added in 3.0.

+0

Danke, es scheint, das ist der Arbeitsansatz für uns. –

+1

Großartig - der Fehler ist behoben und 4.2.7 sollte in der nächsten Woche oder so veröffentlicht werden. –