首页 文章

如何操作WSO2 ESB中的原生Json?

提问于
浏览
0

我正在尝试在REST-API的json-request-reply场景中操作数据 .

为了简化我的问题,假设我想用有效负载内的'd'替换所有'b'字符 .

有没有办法让我在json数据上本地工作,而不是先将数据转换为XML?

我正在尝试构建一个自定义类中介来放入我的OutSequence,但由于我只能访问MessageContext,它将有效负载视为XML,因此我遇到了问题 .

问题是json无法转换为XML和从XML转换 .

在它的结构中有这个部分:

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

“$”属性是有效的json,但由于WSO2 ESB始终在其MessageContext中将数据作为XML处理,因此它无法将该属性显然转换为标记,所以每当我做

MessageContext.getEnvelope().getBody()

在我的 class 调解员中,回应是:

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

缺少$属性 .

我正在使用Message构建器:org.apache.synapse.commons.json.JsonStreamBuilder和formatter:org.apache.synapse.commons.json.JsonStreamFormatter

在正常情况下传递内容(否则它将在XML到JSON处理步骤中失败) . 但是,我必须有一种方法可以将数据作为本机JSON(或作为本机String?)来操作,或许可以获取InputStream并从中操纵数据?但我找不到从消息上下文到达InputStream的方法?

1 回答

  • 0

    事实证明,WSO2本身已经编写了逻辑来处理$ -characters .

    从他们的支持文件(https://docs.wso2.com/display/ESB481/JSON+Support):

    构建XML元素时,当ESB作为JSON键的第一个字符出现时,它会以特殊方式处理'$'字符和数字 .

    $ -character在XML表示中被替换为“JsonReader_PS” . 但是,我查看了这个代码(爱开源),这是处理这种情况的代码:

    //    "$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;
    }
    

    我们可以看到,代码假设属性将以$ -character开头,并且至少有一个其他字符 . 在我们的情况下,情况并非如此,这就是为什么代码对我们失败并且 property “丢失”的原因 .

    为了避免这种情况,我编写了一个自定义JSONStreamBuilder来替换实际InputStream中的所有$ -characters,以确保正确处理对话 .

    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);
    }
    
    }
    

    在我更换了axis2配置中的JSON流构建器之后,我可以愉快地对我的序列中的有效负载执行任何脚本技术并保留$ -character属性 .

    我希望这可以帮助任何面临同样问题的人 .

相关问题