如何跨格式转换数据

194 阅读2分钟

       最近因为工作调整,转向了供应链相关的工作;需要对接不同的第三方公司,每个公司的http接口返回或者请求的数据格式不一,有些公司使的报文使用xml,有些公司 使用json;不可能每次对接第三方,我们都要写一个javabean去适配他们的数据结构,所以如何处理和转换这种数据就显得尤为重要。

      我们都知道json、xml、javaBean之间可以互相转换,为了解决这个问题;我们需要寻找到一个能作为中间转换的数据类型,它既能转换为不同格式的数据类型,也 能支持同一种类型中数据结构进行优雅转换,并且能简化开发,减少系统压力。json可以可以实现转换为不同格式的数据类型,但是无法满足同类型数据结构的优雅转换 ;javaBean可以实现不同格式的数据,但是不能简化开发,因为需要写不同的java对象去转换相关的数据结构。反观xml,则能满足上诉基本的条件。那我们可以使用xml作为中间的转换类型,统一使用xml进行转换。

如何使用

  1. 编写核心转换类

    public String transform(String str, String model) {
        StringReader strReader = null;
        StringReader modelReader = null;
        StringWriter writer = new StringWriter();
        String result = null;
        try {
            strReader = new StringReader(str);
            modelReader = new StringReader(model);
            TransformerFactory factory = TransformerFactory.newInstance();
            Source xslt = new StreamSource(modelReader);
            xslt.setSystemId("http://example.org/some.xsl");
            Transformer transformer = factory.newTransformer(xslt);
            Source text = new StreamSource(strReader);
            text.setSystemId("http://example.org/some.xml");
            transformer.transform(text, new StreamResult(writer));
            strReader.close();
            strReader = null;
            modelReader.close();
            modelReader = null;
            if (writer != null) {
                result = writer.getBuffer().toString();
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                strReader.close();
                strReader = null;
                modelReader.close();
                modelReader = null;
                writer.flush();
                writer.close();
            } catch (Exception e) {
            }
            writer = null;
        }
        return null;
    }
    
    其中str为转换前的xml报文,model为转换时调用的本地xsl文件;
    
    2. 编写xsl文件,解析第三方的报文。
     如下面代码所示,能把根节点为Root的Msg节点的信息赋给msg节点中
    
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:lxslt="http://xml.apache.org/xslt"
                    exclude-result-prefixes="lxslt">
        <xsl:output method="xml"/>
        <xsl:template match="/">
            <msg>
                <xsl:value-of select="Root/Msg"></xsl:value-of>
            </msg>
        </xsl:template>
    </xsl:stylesheet>
    
    3. 将转换之后的xml报文转换为json或者javaBean对象
    //转换为javaBean
    public static <T> T xml2Obj(String xml, Class<T> clazz, String charSet) {
        ByteArrayInputStream byteArrayInputStream = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(xml.getBytes(charSet));
            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            return (T) unmarshaller.unmarshal(byteArrayInputStream);
        } catch (Exception e) {
            logger.error("将xml转换为对象失败", e);
        } finally {
            try {
                byteArrayInputStream.close();
            } catch (Exception e1) {
            }
        }
        return null;
    }
    
    //转换为json对象
    public static String xml2Json(String xml) {
        try {
            XMLSerializer xmlSerializer = new XMLSerializer();
            return xmlSerializer.read(xml).toString();
        } catch (Exception e) {
            logger.error("xml 转 json 失败,xml={}",xml, e);
            return null;
        }
    }