要在PI MM中获取ORIGINAL json字符串#PI REST适配器#

2020-08-22 07:33发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


嗨,大家好,

我正在尝试实现PI REST案例,但仍然没有出路,这是如此困难,我需要您的帮助。

我制作一个示例案例来解释我想要做什么。

场景类似于:

  • 1.System TSTA正在通过PI向SAP发送消息
  • 2。"有效载荷1"类似于:{"名称":"尼尔","年龄":" 18"}
  • 3。在PI中运行PI Message Mapping之后,我想要得到的是" Payload 2",
  • 4。最后,在SAP中,需要以下数据,在JSON_STRING中,我恰好需要从TSTA发送的 ORIGINAL json字符串。 不需要任何转换。

现在我有问题:

  • 1。我不知道如何配置REST发送者通道。 我的意思是,我知道如何在常规情况下使用REST CC,但这是一种。 我尝试检查或不检查"转换为XML",都失败了。
  • 2。如果未选中"转换为XML",则我不知道如何构建ESR,尤其是在消息映射中。 我知道目标消息类型是什么,但不知道源消息类型应该是什么样。
  • 这就是我要面对的问题,希望我能说清楚。 对我来说,最难的部分是在消息映射中获取原始的JSON字符串。
  • 并且确实需要你们的提示和建议。
  • 谢谢。

(38.9 kB)

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


嗨,大家好,

我正在尝试实现PI REST案例,但仍然没有出路,这是如此困难,我需要您的帮助。

我制作一个示例案例来解释我想要做什么。

场景类似于:

  • 1.System TSTA正在通过PI向SAP发送消息
  • 2。"有效载荷1"类似于:{"名称":"尼尔","年龄":" 18"}
  • 3。在PI中运行PI Message Mapping之后,我想要得到的是" Payload 2",
  • 4。最后,在SAP中,需要以下数据,在JSON_STRING中,我恰好需要从TSTA发送的 ORIGINAL json字符串。 不需要任何转换。

现在我有问题:

  • 1。我不知道如何配置REST发送者通道。 我的意思是,我知道如何在常规情况下使用REST CC,但这是一种。 我尝试检查或不检查"转换为XML",都失败了。
  • 2。如果未选中"转换为XML",则我不知道如何构建ESR,尤其是在消息映射中。 我知道目标消息类型是什么,但不知道源消息类型应该是什么样。
  • 这就是我要面对的问题,希望我能说清楚。 对我来说,最难的部分是在消息映射中获取原始的JSON字符串。
  • 并且确实需要你们的提示和建议。
  • 谢谢。

(38.9 kB)
付费偷看设置
发送
12条回答
半个程序猿
1楼-- · 2020-08-22 08:19

嗨!

我只想重复一遍:不要在发送方通道中使用任何转换,使用Java映射将有效负载读取到文本字符串,将副本保存到专用变量,使用适当的格式将json字符串转换为xml Java类和构建输出消息包含单独的元素,其中包含您保存的源JSON内容。

Evgeniy。

Cikesha
2楼-- · 2020-08-22 08:03

对不起,我发现我错过了一些非常重要的内容。

由于某种原因,系统TSTA会以不同的提交顺序发送JSON字符串,就像以下两种情况一样。 然后在目标字段" json_string"中,我需要与发送的TSTA完全相同的字符串。 因此,我需要第1列和第2列始终相同,即使每个空格也是如此。

如果我在REST CC中使用"转换为XML",然后在消息映射中将XML转换回JSON,我想我会在" json_sting"中得到2个相同的值(因为我必须设置固定字段顺序 日期类型优先),那不是我想要的。

代楠1984
3楼-- · 2020-08-22 08:00

也使用与屏幕快照中显示的相同的结构作为发件人。

Nir深蓝
4楼-- · 2020-08-22 08:05

对此有什么解决方案? 请帮助分享。 谢谢!

我很惊讶无法从消息日志中读取有效负载。 必须有一种通过UDF读取它的方法。

渐行渐远_HoldOn
5楼-- · 2020-08-22 08:11

陈Chen,

哦! 但我不知道为什么要在JSON字符串中使用相同的顺序,即使顺序不同,其值也将相同。 我有时间,所以我想为什么不为您编写代码以简化工作。 是这样的:

包org.test.one;


 导入java.io.ByteArrayOutputStream;
 导入java.io.InputStream;
 导入java.io.StringReader;


 导入javax.xml.parsers.DocumentBuilder;
 导入javax.xml.parsers.DocumentBuilderFactory;
 导入javax.xml.transform.OutputKeys;
 导入javax.xml.transform.Transformer;
 导入javax.xml.transform.TransformerException;
 导入javax.xml.transform.TransformerFactory;
 导入javax.xml.transform.dom.DOMSource;
 导入javax.xml.transform.stream.StreamResult;


 导入org.json.JSONObject;
 导入org.json.XML;
 导入org.w3c.dom.Document;
 导入org.w3c.dom.Element;
 导入org.w3c.dom.Node;
 导入org.w3c.dom.NodeList;
 导入org.xml.sax.InputSource;


 导入com.sap.aii.mapping.api.AbstractTransformation;
 导入com.sap.aii.mapping.api.StreamTransformationException;
 导入com.sap.aii.mapping.api.TransformationInput;
 导入com.sap.aii.mapping.api.TransformationOutput;


/**
  * @作者AnoopRai
 */
 公共类JSON2XML_JM扩展了AbstractTransformation {


 最后的静态字符串XMLDOC_NAME =" MT_Name"; //根据您的消息类型替换
 最后的静态字符串XMLDOC_NAMESPACE =" urn://test"; //根据您的NS替换它


 @Override
 公共无效变换(TransformationInput tInput,TransformationOutput tOutput)
 引发StreamTransformationException {


 尝试{
 InputStream输入= tInput.getInputPayload()。getInputStream();
 byte [] bt =新的byte [input.available()];
 input.read(bt);
 字符串sourceString =新的String(bt);

 JSONObject json =新的JSONObject(sourceString);
 字符串xmlSource = XML.toString(json," SourceMessage");


 DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance()。newDocumentBuilder();
 文档doc = dBuilder.newDocument();
 doc.setXmlStandalone(true);
 元素docElement = doc.createElementNS(XMLDOC_NAMESPACE,XMLDOC_NAME);

 文档docSource = dBuilder.parse(new InputSource(new StringReader(xmlSource)));
 节点sourceNode = doc.importNode(docSource.getFirstChild(),true);
 NodeList nList = sourceNode.getChildNodes();


 而(nList.getLength()!= 0)
 docElement.appendChild(nList.item(0));

 元素jsonText = doc.createElement(" jsonText");
 jsonText.appendChild(doc.createTextNode(sourceString));
 docElement.appendChild(jsonText);


 doc.appendChild(docElement);

 tOutput.getOutputPayload()。getOutputStream()。write(documentToByte(doc," UTF-8"," 4"));


 } catch(Exception e){
 抛出新的StreamTransformationException(e.getMessage(),e);
 }
 }

 公共字节[] documentToByte(文档doc,字符串编码,字符串indentFactor)
 引发StreamTransformationException {
 尝试{
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 TransformerFactory TransformerFactory = TransformerFactory.newInstance();


 变压器变压器= transformerFactory.newTransformer();
 如果(indentFactor!= null)
 Transformer.setOutputProperty(" {http://xml.apache.org/xslt}indent-amount",indentFactor);
 Transformer.setOutputProperty(OutputKeys.INDENT,"是");
 Transformer.setOutputProperty(OutputKeys.ENCODING,编码);
 DOMSource source =新的DOMSource(doc);
 StreamResult结果=新的StreamResult(bos);


 Transformer.transform(来源,结果);
 返回bos.toByteArray();
 } catch(TransformerException e){
 抛出新的StreamTransformationException(
 "无法将XML文档转换为字节数组:" + e.getMessage());
 }
 }
 } 

请添加 org.json jar 在库中并将JavaMap导出为可运行的jar。

JavaMap的测试结果:

我也尝试使用我的旧方法,因为我们需要按记录传递JSON字符串,而这种类型的JavaMap没有用。 但是,是的,在UDF中,您将不会以与从源系统接收到的顺序相同的顺序获得元素。 我还附上了相同的屏幕截图。

使用UDF:

UDF代码:

结果:

这两种方法在逻辑上都是正确的,只是一种方法比其他方法需要更多行定制代码。 让我知道您是否还有其他问题。

此致

Anoop Rai

lukcy2020
6楼-- · 2020-08-22 08:01

HI Evgeniy,

很高兴再次见到你,我完全同意你的意见,这正是我正在努力的目标。

但是,我仍然要解决2个关键问题:

1。 "使用Java映射将有效负载读取到文本字符串"。 我不知道在哪里以及如何去做。 在发送者频道中?

2。 在消息映射中,我应该使用什么作为"源消息"?

现在,我在发件人通道中不进行任何转换,并在消息映射中将以下消息类型用作源消息,

然后我得到如下错误:

正在捕获异常的调用消息传递系统:无法解析XML消息有效负载以提取用于确定接收者的操作org.xml.sax.SAXParseException; lineNumber:1; columnNumber:1; 序言中不允许包含内容。

我猜这个错误发生在json有效负载进入消息映射,并且与源消息类型不匹配时。

期待您的进一步答复。

小事。

一周热门 更多>