后台数据传输-XML

1. 技术目标

  • 目标01:如何组装xml的vo对象
  • 目标02:ObjectMapper和XmlMapper类的熟练使用
  • 目标03:POJO2XML
  • 目标04:XML2POJO

2. 技术介绍

官方GitHub地址

最近在公司做一个对接开发票系统的工作,工作也刚好一年了,原本以为会是一件很简单的事情,更不会花费多久的时间,但是当我打开对接公司发的接口文档,我的眼前感到了一阵困惑,怎么数据的传输都是XML的格式呢?之前我曾经写过一篇后台数据传输-JSON,介绍了各种JSON数据格式的传输,而XML是进公司这么久以来,第一次接触这样的接口,只能说明我的水平太cai了!在网上搜索和很久,发现大多都是通过[DOM、SAX、DOM4J、JDOM、Xstream],自己也按照尝试了多次,虽然可以实现数据的组转,但是这也太kegndie了吧!幸好在公司认识一个马哥的同事,在他的指点下,完成了第一个demo的实现,今天闲来无事,在此和大家分享一下,愿共同进步!话不多说,直接开始上代码了。

3. 环境配置

3.1 开发配置
  • JDK 1.8 或更高版本
  • Maven 3 或更高版本
  • MySQL Server 5.6
3.2 技术栈
  • Spring Boot
  • Jackson XML annotations
  • MySQL

4. 技术实践

4.1 创建项目
4.2 创建结构
4.2.1 pom.xml引入依赖
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>
4.2.2 属性文件配置
4.3 主要代码
4.3.1 XML数据格式
<?xml version='1.0' encoding='UTF-8'?>
<root>
    <header/>
    <body id="1" size="2">
        <datas>
            <data k6="22">
                <k1>k1</k1>
                <k3>
                    <ki>1</ki>
                    <ki>2</ki>
                </k3>
                <k5>1</k5>
                <k5>2</k5>
                <k7>a7b</k7>
                <k8>
                    <a>a7b</a>
                </k8>
                <k9>
                    <![CDATA[java]]>
                </k9>
                <k2>12</k2>
                <k4>
                    <ka>1</ka>
                    <ka>2</ka>
                </k4>
            </data>
            <data>
                <k1/>
                <k5/>
                <k7/>
                <k8/>
                <k9/>
                <k2/>
            </data>
        </datas>
    </body>
</root>
4.3.2 创建VO对象
package cn.hacz.edu.vo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "root")
public class Root {
    private Header header;

    private Body body;

    public Header getHeader() {
        return header;
    }

    public void setHeader(Header header) {
        this.header = header;
    }

    public Body getBody() {
        return body;
    }

    public void setBody(Body body) {
        this.body = body;
    }

}

package cn.hacz.edu.vo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Header {

}

package cn.hacz.edu.vo;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Body {

    @JacksonXmlProperty(isAttribute = true, localName = "id")
    private String id;

    @JacksonXmlProperty(isAttribute = true, localName = "size")
    private Integer size;
    /**
     * List集合形式
     */
    @JacksonXmlElementWrapper(localName = "datas")
    @JacksonXmlProperty(localName = "data")
    private List<Data> datas;

    public List<Data> getDatas() {
        return datas;
    }

    public void setDatas(List<Data> datas) {
        this.datas = datas;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getSize() {
        return getDatas().size();
    }

    public void setSize(Integer size) {
        this.size = size;
    }

}

package cn.hacz.edu.vo;

import java.util.Collection;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Data {
    private String k1;

    @JacksonXmlProperty(localName = "k2")
    private Integer k2;

    @JacksonXmlElementWrapper(localName = "k3")
    private Collection<String> ki;

    @JacksonXmlElementWrapper(localName = "k4")
    @JacksonXmlProperty(localName = "ka")
    private Collection<String> k4;

    @JacksonXmlElementWrapper(localName = "k5", useWrapping = false)
    private Collection<String> k5;

    @JacksonXmlProperty(isAttribute = true)
    private Integer k6;
    private DataValue01 k7;
    private DataValue02 k8;
    // 序列化时是否总是使用 CDATA 块
    @JacksonXmlCData(value = true)
    private String k9;

    public String getK1() {
        return k1;
    }

    public void setK1(String k1) {
        this.k1 = k1;
    }

    public Integer getK2() {
        return k2;
    }

    public void setK2(Integer k2) {
        this.k2 = k2;
    }

    public Collection<String> getKi() {
        return ki;
    }

    public void setKi(Collection<String> ki) {
        this.ki = ki;
    }

    public Collection<String> getK4() {
        return k4;
    }

    public void setK4(Collection<String> k4) {
        this.k4 = k4;
    }

    public Collection<String> getK5() {
        return k5;
    }

    public void setK5(Collection<String> k5) {
        this.k5 = k5;
    }

    public Integer getK6() {
        return k6;
    }

    public void setK6(Integer k6) {
        this.k6 = k6;
    }

    public DataValue01 getK7() {
        return k7;
    }

    public void setK7(DataValue01 k7) {
        this.k7 = k7;
    }

    public DataValue02 getK8() {
        return k8;
    }

    public void setK8(DataValue02 k8) {
        this.k8 = k8;
    }

    public String getK9() {
        return k9;
    }

    public void setK9(String k9) {
        this.k9 = k9;
    }

}


package cn.hacz.edu.vo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;

public class DataValue01 {
    @JacksonXmlText
    private String a;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

}

package cn.hacz.edu.vo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;

public class DataValue02 {
    @JacksonXmlText(value = false)
    private String a;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }
}


4.3.3 ObjectMapper和XmlMapper
    public static XmlMapper getxmlMapper() {
        // 重要:创建XmlMapper; 它将使用适当的工厂,解决方法。
        XmlMapper xmlMapper = new XmlMapper();
        // 格式化代码
        xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
        // <?xml version='1.0' encoding='UTF-8'?>
        xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
        return xmlMapper;
    }
4.3.4 POJO2XML
        String writeValueAsString = getxmlMapper().writeValueAsString(root);
        System.out.println(writeValueAsString);
4.3.5 XML2POJO
        File file = new File("D:\\1.xml");
        // 02、XML文件转成POJO对象
        Root readValue = getxmlMapper().readValue(file, Root.class);
        List<Data> datas2 = readValue.getBody().getDatas();
        for (Data data : datas2) {
            System.out.println(data.getKi());
        }

解析xml按照一定顺序:@JsonPropertyOrder({"classStr","size"})

5. 技术总结

5.1

6. 代码下载

本章以及后续章节的源码地址我都会分享出来,请大家自行下载以及git clone。
SpringBoot相关系列文章请访问:目录:SpringBoot学习目录

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容