2016-03-31 3 views
0

Ich versuche, Daten in einem JSON-Anfrage-Antwort-Szenario für eine REST-API zu manipulieren.Wie native Json in WSO2 ESB zu manipulieren?

Um mein Problem zu vereinfachen, nehmen wir an, ich möchte alle 'b' Zeichen durch ein 'd' innerhalb der Nutzlast ersetzen.

Gibt es eine Möglichkeit für mich, nativ auf den JSON-Daten zu arbeiten und die Daten nicht zuerst in XML zu konvertieren?

Ich versuche, einen benutzerdefinierten Klassenmediator zu erstellen, um meine OutSequence zu setzen, aber da ich nur Zugriff auf den MessageContext habe, der die Payload als XML behandelt, stoße ich auf Probleme.

Das Problem ist, dass der JSON nicht zu und von XML umgewandelt werden kann.

Dieser Teil innerhalb seiner Struktur hat:

"Destination": { 
     "name": "abc", 
     "type": "ST", 
     "$": "\n" 
    } 

Das „$“ Eigenschaft gilt json, aber da WSO2 ESB immer Daten als XML verarbeiten innerhalb seiner Message, es diese Eigenschaft, um Tags nicht verwandeln kann offensichtlich, so, wenn ich

MessageContext.getEnvelope().getBody() 

in meiner Klasse Vermittler tun, die Antwort ist:

<Destination> 
    <name>abc</name> 
    <type>ST</type> 
</Destination> 

Die Eigenschaft $ fehlt.

Ich verwende die Nachricht Bauer: org.apache.synapse.commons.json.JsonStreamBuilder und Formatierer: org.apache.synapse.commons.json.JsonStreamFormatter

Um im Normalfall durch den Inhalt passieren (andernfalls würde es im XML-zu-JSON-Verarbeitungsschritt fehlschlagen. Aber es muss einen Weg für mich geben, die Daten als natives JSON (oder als ein nativer String?) Zu manipulieren, vielleicht den InputStream zu erreichen und die Daten davon zu manipulieren? Aber ich kann keine Möglichkeit finden, über den Nachrichtenkontext zum InputStream zu gelangen.

Antwort

0

Stellt sich heraus, dass WSO2 selbst Logik geschrieben hat, um $ -Zeichen zu behandeln.

Aus ihrer Unterstützung-Dokument (https://docs.wso2.com/display/ESB481/JSON+Support):

Wenn XML-Elemente erstellen, die ESB behandelt das Zeichen ‚$‘ und Ziffern in besonderer Weise, wenn sie als erstes Zeichen von erscheinen ein JSON Schlüssel.

Das $ -Zeichen wird in der XML-Darstellung als "_JsonReader_PS_" ersetzt. Allerdings sah ich in den Code für diese (Liebe Open Source), und dies ist der Code diesen Fall bearbeitet:

// "$a" replace with "_JsonReader_PS_a" 
private String replaceInvalidCharacters(String keyString){ 
    if(Pattern.compile("^[0-9]").matcher(keyString).find()) { 
     return "_JsonReader_PD_" + keyString; 
    } else if (keyString.startsWith("$")){ 
     return "_JsonReader_PS_" + keyString.substring(1); 
    } else 
     return keyString; 
} 

Wie wir sehen können, ist der Code die Eigenschaft mit einem $ -Zeichen geht davon aus beginnen und haben mindestens ein anderes Zeichen. Dies ist in unserem Fall nicht der Fall, weshalb der Code für uns fehlschlägt und die Eigenschaft "verloren" ist.

Um dies zu umgehen, schrieb ich einen benutzerdefinierten JSONStreamBuilder, um alle $ -Zeichenketten im tatsächlichen InputStream zu ersetzen, um sicherzustellen, dass die Konversation korrekt gehandhabt wurde.

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

import org.apache.axiom.om.OMElement; 
import org.apache.axis2.AxisFault; 
import org.apache.axis2.builder.Builder; 
import org.apache.axis2.context.MessageContext; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.apache.synapse.commons.json.JsonStreamBuilder; 

/* 
* As WSO2 JSON parser can't handle single $ properties when converting between JSON and XML 
* This custom JSON Stream builder replaces all $ signs with the constant '_JsonReader_PS_', 
* which the WSO2 parser treats as a $ sign when transforming. 
*/ 

public class CustomJsonStreamBuilder implements Builder { 

private static final Log logger = LogFactory.getLog(CustomJsonStreamBuilder.class.getName()); 

JsonStreamBuilder jsonStreamBuilder = new JsonStreamBuilder(); 

public OMElement processDocument(InputStream arg0, String arg1, MessageContext arg2) throws AxisFault { 

    logger.debug("Processing input stream for custom JSON stream builder"); 

    BufferedReader br = null; 
    StringBuilder sb = new StringBuilder(); 

    String line; 
    try { 

     br = new BufferedReader(new InputStreamReader(arg0)); 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
     } 

     String input = sb.toString(); 

     /* 
     * WSO2 JSON parser treats _JsonReader_PS_ as $ in JSON structure 
     */ 

     input = input.replace("$", "_JsonReader_PS_"); 
     InputStream is = new ByteArrayInputStream(input.getBytes("utf-8")); 

     if (br != null) { 
      try { 
       br.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     return jsonStreamBuilder.processDocument(is, arg1, arg2); 

    } catch (Exception e) { 
     e.printStackTrace(); 
     logger.error("Problem processing input stream for custom JSON stream builder", e); 
    } 

    return jsonStreamBuilder.processDocument(arg0, arg1, arg2); 
} 

} 

Nachdem ich die JSON-Stream-Builder in der axis2 Konfiguration ersetzt konnte ich auf der Nutzlast in meinen Sequenzen keine Skriptingverfahren glücklich machen und das $ -Zeichen Eigentum zu halten.

Ich hoffe, das hilft jedem, der das gleiche Problem wie ich konfrontiert.