SAP PI Java Mapping中使用GSON实现XML转JSON遇问题求助
问题分析与解决方案
你的核心问题在于没有先解析XML结构,而是直接把XML字符串当成普通文本传给Gson,所以Gson只是把整个XML转成了JSON格式的字符串(带转义字符),而不是按照XML的层级结构生成对应的JSON对象。
要解决这个问题,我们需要分三步走:把XML解析成Java对象(POJO),再用Gson把POJO转成JSON。下面是具体实现:
第一步:定义对应XML结构的POJO类
首先要创建和源XML结构完全匹配的Java类,Gson可以直接把这些对象转换成JSON:
package xmlgsonjson; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; // 对应根节点<data> @XmlRootElement(name = "data") public class Data { private String ERP; private String Shiptoparty; private String Shippingpoint; private String Issuedate; private List<Product> products; @XmlElement(name = "ERP") public String getERP() { return ERP; } public void setERP(String ERP) { this.ERP = ERP; } @XmlElement(name = "Shiptoparty") public String getShiptoparty() { return Shiptoparty; } public void setShiptoparty(String shiptoparty) { Shiptoparty = shiptoparty; } @XmlElement(name = "Shippingpoint") public String getShippingpoint() { return Shippingpoint; } public void setShippingpoint(String shippingpoint) { Shippingpoint = shippingpoint; } @XmlElement(name = "Issuedate") public String getIssuedate() { return Issuedate; } public void setIssuedate(String issuedate) { Issuedate = issuedate; } @XmlElement(name = "products") public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } } // 对应<products>节点 class Product { private String Unit; private Double QTY; private String SKUno; @XmlElement(name = "Unit") public String getUnit() { return Unit; } public void setUnit(String unit) { Unit = unit; } @XmlElement(name = "QTY") public Double getQTY() { return QTY; } public void setQTY(Double QTY) { this.QTY = QTY; } @XmlElement(name = "SKUno") public String getSKUno() { return SKUno; } public void setSKUno(String SKUno) { this.SKUno = SKUno; } }
第二步:修改Mapping类的转换逻辑
替换你原来的transform方法,用JAXB解析XML到POJO,再用Gson转成JSON:
package xmlgsonjson; import java.io.InputStream; import java.io.OutputStream; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sap.aii.mapping.api.AbstractTransformation; import com.sap.aii.mapping.api.StreamTransformationException; import com.sap.aii.mapping.api.TransformationInput; import com.sap.aii.mapping.api.TransformationOutput; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; public class MakeItJSONByGSON extends AbstractTransformation { @Override public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException { try { InputStream inputStream = in.getInputPayload().getInputStream(); OutputStream outputStream = out.getOutputPayload().getOutputStream(); // 1. 用JAXB把XML解析成Data对象 JAXBContext jaxbContext = JAXBContext.newInstance(Data.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); Data data = (Data) unmarshaller.unmarshal(inputStream); // 2. 用Gson把Data对象转成格式化的JSON Gson gson = new GsonBuilder().setPrettyPrinting().create(); String jsonOutput = gson.toJson(data); // 3. 输出JSON到PI的payload outputStream.write(jsonOutput.getBytes()); } catch (Exception e) { // 抛出PI能识别的异常,方便排查问题 throw new StreamTransformationException("XML to JSON transformation failed", e); } } }
关键注意事项
- 依赖配置:确保SAP PI的映射库中添加了Gson的jar包(
gson-x.x.x.jar),JAXB在Java EE环境中默认自带,不需要额外添加。 - 字段类型选择:如果需要保留
ERP、Shiptoparty等字段的前导0,必须用String类型;如果转成Long/Integer会丢失前导0。 - XML空格处理:JAXB会自动忽略XML中的空白字符(比如
QTY字段的末尾空格),解析时会正确转换成Double类型。
修正后的预期输出
(注:你给出的预期输出有语法错误,比如对象属性间缺少逗号,且data不应该是数组,以下是正确的输出):
{ "ERP": "0080001", "Shiptoparty": "0088000", "Shippingpoint": "503", "Issuedate": "20181102", "products": [ { "Unit": "L", "QTY": 2.0, "SKUno": "000000000011" }, { "Unit": "L", "QTY": 0.0, "SKUno": "000000000011000078" } ] }
内容的提问来源于stack exchange,提问作者Kaushik
相关产品推荐
相关产品推荐

