JiBX 的实操

news2024/11/24 11:00:34

JiBX 的实操

  • 介绍
  • 基本概念
    • BECL 介绍
    • JiBX 基础概念
  • 开发
    • jar 依赖
      • BECL
      • JiBX
    • POJO 实体类
      • Order
      • Address
      • Customer
      • Shipping
      • OrderFactory 工厂类
    • 使用ant 来生成XML和POJO对象的绑定关系
      • idea 使用ant
      • ant 脚本 build.xml
      • ant 添加 build.xml
        • binding.xml
      • 报错问题解决
  • 测试
    • TestOrder
      • 测试结果 如图:
        • 错误解决
  • Bug遗留

介绍

JiBX是一款非常优秀的XML(Extensible Markup Language)数据绑定框架。它提供灵活的绑定映射文件,实现数据对象与XML文件之间的转换,并不需要修改既有的Java类。并且转换效率极高。
XML 已经成为目前程序开发配置的重要组成部分了,JiBX 操作XML 的优点有:
(1)转换效率高
(2)配置绑定文件简单
(3)不需要操作xpath文件
(4)不需要写属性的get/set 方法
(5)对象属性名与XML文件element名可以不同等

基本概念

使用JiBX 绑定XML文档与Java对象需要分两步走:
(1)绑定XML文件,也就是映射XML文件与Java对象之间的对应关系
(2)在运行时,实现XML文件与Java实例之间的互相转换。我们要的就是能够 实现 这个功能。

BECL 介绍

在运行程序之前,需要先配置绑定文件并进行绑定,在绑定过程中它将会动态地修改程序中相应的class文件,主要是生成对应对象实例的方法和添加被绑定标记的属性JiBX_bindingList。 使用的技术是BECL(Byte Code Engineering Library),BCEL 是Apache Software Foundation的Jakarta 项目的一部分,也是目前Java classworking 最广泛使用的一种框架,它可以让我们深入JVM汇编语言进行操作。

JiBX 基础概念

Unmarshal 数据分解,将XML文件转换成Java对象
Marshal 数据编排 将Java对象编排成规范的XML文件。
JiBX 在 Unmarshal/Marshal 上如此高效,这要归功于使用了XPPXml Pull Parsing)技术,而不是使用基于树形方式,将整个文档写入内存,然后进行操作的DOM。也不是使用基于事件流的SAX。XPP使用的是不断增加的数据流处理方式,同时允许在解析XML文件时中断。

开发

jar 依赖

BECL

       <dependency>
            <groupId>org.apache.bcel</groupId>
            <artifactId>bcel</artifactId>
            <version>6.7.0</version>
        </dependency>

JiBX

        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-run</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-extras</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-bind</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-tools</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-schema</artifactId>
            <version>1.4.2</version>
        </dependency>

POJO 实体类

Order

public class Order {
    private long orderNumber;
    private Customer customer;

    /**
     * Billing address information
     */
    private Address bilTo;

    private String shipping;

    /**
     * Shipping address information. If missing ,the billing address is also
     * used as the shipping address.
     */
    private Address shipTo;

    private Float total;

    public long getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(long orderNumber) {
        this.orderNumber = orderNumber;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public Address getBilTo() {
        return bilTo;
    }

    public void setBilTo(Address bilTo) {
        this.bilTo = bilTo;
    }

    public String getShipping() {
        return shipping;
    }

    public void setShipping(String shipping) {
        this.shipping = shipping;
    }

    public Address getShipTo() {
        return shipTo;
    }

    public void setShipTo(Address shipTo) {
        this.shipTo = shipTo;
    }

    public Float getTotal() {
        return total;
    }

    public void setTotal(Float total) {
        this.total = total;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderNumber=" + orderNumber +
                ", customer=" + customer +
                ", bilTo=" + bilTo +
                ", shipping=" + shipping +
                ", shipTo=" + shipTo +
                ", total=" + total +
                '}';
    }
}

Address

public class Address {
    /**
     * First line of street information (required).
     */
    private String street1;

    /**
     * Second line of street information (optional).
     */
    private String street2;

    private String city;

    /**
     * State abbreviation (required for the U.S. and Canada, optional otherwise )
     */

    private String state;

    /**
     * Postal code (required for the U.S. and Canada ,optional otherwise ).
     */
    private String postCode;

    /**
     * Country name (optional ,U.S. assumed if not supplied).
     */
    private String country;


    public String getStreet1() {
        return street1;
    }

    public void setStreet1(String street1) {
        this.street1 = street1;
    }

    public String getStreet2() {
        return street2;
    }

    public void setStreet2(String street2) {
        this.street2 = street2;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return "Address{" +
                "street1='" + street1 + '\'' +
                ", street2='" + street2 + '\'' +
                ", city='" + city + '\'' +
                ", state='" + state + '\'' +
                ", postCode='" + postCode + '\'' +
                ", country='" + country + '\'' +
                '}';
    }
}

Customer

public class Customer {
    private long customerNumber;
    /**
     * Personal name
     */
    private String firstName;

    /**
     * Family name .
     */
    private String lastName;

    /**
     * Middle name(s) if any.
     */
    private List<String> middleNames;


    public long getCustomerNumber() {
        return customerNumber;
    }

    public void setCustomerNumber(long customerNumber) {
        this.customerNumber = customerNumber;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public List<String> getMiddleNames() {
        return middleNames;
    }

    public void setMiddleNames(List<String> middleNames) {
        this.middleNames = middleNames;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "customerNumber=" + customerNumber +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", middleNames=" + middleNames +
                '}';
    }
}

Shipping

public class Shipping {
    public final static String STANDARD_MAIL="STANDARD_MAIL";
    public final static String PRIORITY_MAIL="PRIORITY_MAIL";
    public final static String INTERNATIONAL_MAIL="StringINTERNATIONAL_MAIL";
    public final static String DOMESTIC_EXPRESS="DOMESTIC_EXPRESS";
    public final static String INTERNATIONAL_EXPRESS="INTERNATIONAL_EXPRESS";
}

OrderFactory 工厂类

public class OrderFactory {
    public static Order create(int number){
        Order order=new Order();
        //orderNumber
        order.setOrderNumber(number);
        //total
        order.setTotal(9999.999f);
        //customer
        Customer customer=new Customer();
        customer.setFirstName("echo");
        customer.setLastName("tong");
        List<String>list=new ArrayList<>();
        list.add("666");
       // list.add("555");
        customer.setCustomerNumber(123);
        //customer.setMiddleNames(list);
        order.setCustomer(customer);

        //billTo
        Address billTo=new Address();
        billTo.setStreet1("西乡大道");
        billTo.setCity("深圳市");
        billTo.setState("广东省");
        billTo.setPostCode("123321");
        billTo.setCountry("中国");
        order.setBilTo(billTo);
        //shipping
        order.setShipping(Shipping.INTERNATIONAL_MAIL);
        //shipTo
        Address shipTo=new Address();
        shipTo.setStreet1("西乡大道");
        shipTo.setCity("深圳市");
        shipTo.setState("广东省");
        shipTo.setPostCode("123321");
        shipTo.setCountry("中国");
        order.setShipTo(shipTo);


        return order;
    }
}

使用ant 来生成XML和POJO对象的绑定关系

idea 使用ant

idea 里面有自带的ant 工具。打开方式 View —Tool Windows–Ant
在这里插入图片描述
打开后,右上角就会有一个蚂蚁图标。如下图
在这里插入图片描述

ant 脚本 build.xml

需要修改的地方主要有两个:
一个是 jibx和bcel 依赖的路径。
另一个是POJO实体类的全路径

<?xml version="1.0" encoding="utf-8"?>
<project default="main" basedir=".">
    <path id="classpath">
        <dirset dir="${basedir}/target/classes" />
        <!--由于不需要编译单元测试代码,就注掉了下面的内容-->
        <!--<dirset dir="${basedir}/target/test-classes" />-->

        <!--下面目录为本地maven仓库的jibx和bcel的jar包的绝对路径  同学们也可以采用相对路径-->
        <fileset dir="D:/ProgramFiles/apache-maven-3.6.3/conf/repository/org/jibx/jibx-bind/1.4.2/" includes="*.jar" />
        <fileset dir="D:/ProgramFiles/apache-maven-3.6.3/conf/repository/org/jibx/jibx-run/1.4.2/" includes="*.jar" />
        <fileset dir="D:/ProgramFiles/apache-maven-3.6.3/conf/repository/org/apache/bcel/bcel/6.0/" includes="*.jar" />
    </path>
    <!--这个是主任务 , depends 依赖下面写的三个分任务 -->
    <target name="main" depends="compile,bindgen,bind" description="Main target" />
    <target name="compile" description="Compilation target">
        <echo>Building file.</echo>
        <!--相当于运行 javac命令进行源码编译-->
        <javac srcdir="${basedir}/src/main/java" destdir="${basedir}/target/classes" includeantruntime="true" />
    </target>
    <target name="bindgen">
        <echo message="Running BindGen tool" />
        <!--
        相当于运行Java命令生成binding.xml文件 类似于网上说的如下命令 ->
        java -cp ..libx-tools.jar ..BindGen -t 生成文件保存地址 -v 需要绑定文件的class文件 完整包名.类名
        -->
        <java classpathref="classpath" fork="true"  classname="org.jibx.binding.BindingGenerator">
            <!-- 此处写需要生成映射文件的实体类的全类名-->


            <arg value="echo.cn.http.xml.pojo.Address" />
            <arg value="echo.cn.http.xml.pojo.Customer" />
            <arg value="echo.cn.http.xml.pojo.Order" />
          <arg value="echo.cn.http.xml.pojo.Shipping" />
        </java>
    </target>
    <target name="bind">
        <!--将实体类的class和xml映射文件进行绑定-->
        <echo message="Running bind" />
        <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask">
            <classpath refid="classpath">

            </classpath>
        </taskdef>
        <bind binding="${basedir}/binding.xml">
            <classpath refid="classpath"/>
        </bind>
    </target>
</project>

建议放在根目录下,先和我们保持一致,熟练后可以自定义修改。位置如下图所示:
在这里插入图片描述

ant 添加 build.xml

首先 在ant 里面添加build.xml.
然后依次执行 bindgen和bind命令。其中bindgen命令会生成binding.xml文件。即实体类和XML的绑定关系 的描述文件。
bind 命令 会动态的修改实例类的class文件,在里面添加对应的 JiBX_bindingList 属性值,并动态实现 IUnmarshallable和IMarshallable接口,同时会生成实体类的access文件等。
在这里插入图片描述
在这里插入图片描述

binding.xml

<?xml version="1.0" encoding="UTF-8"?>
<binding value-style="attribute">
  <mapping class="echo.cn.http.xml.pojo.Address" name="address">
    <value style="element" name="street1" field="street1" usage="optional"/>
    <value style="element" name="street2" field="street2" usage="optional"/>
    <value style="element" name="city" field="city" usage="optional"/>
    <value style="element" name="state" field="state" usage="optional"/>
    <value style="element" name="post-code" field="postCode" usage="optional"/>
    <value style="element" name="country" field="country" usage="optional"/>
  </mapping>
  <mapping class="echo.cn.http.xml.pojo.Customer" name="customer">
    <value name="customer-number" field="customerNumber"/>
    <value style="element" name="first-name" field="firstName" usage="optional"/>
    <value style="element" name="last-name" field="lastName" usage="optional"/>
    <collection field="middleNames" usage="optional" factory="org.jibx.runtime.Utility.arrayListFactory"/>
  </mapping>
  <mapping class="echo.cn.http.xml.pojo.Order" name="order">
    <value name="order-number" field="orderNumber"/>
    <structure field="customer" usage="optional"/>
    <structure field="bilTo" usage="optional"/>
    <value style="element" name="shipping" field="shipping" usage="optional"/>
    <structure field="shipTo" usage="optional"/>
    <value name="total" field="total" usage="optional"/>
  </mapping>
  <mapping class="echo.cn.http.xml.pojo.Shipping" name="shipping"/>
</binding>

报错问题解决

bindgen 命令可能会报路径不存在。此时需要先编译,生成target目录。可以用Maven的compile命令先执行生成对应的目录即可。

测试

前面 铺垫工作做好了后,我们就来测试以下。

TestOrder

public class TestOrder {
    private IBindingFactory factory=null;

    private StringWriter writer=null;

    private StringReader reader=null;

    private final static String CHARSET_NAME="UTF-8";

    private String encode2Xml(Order order) throws JiBXException, IOException {
       
        factory= BindingDirectory.getFactory(Order.class);
        writer=new StringWriter();
        IMarshallingContext context=factory.createMarshallingContext();
        context.setIndent(2);
        // marshal 将实体类编码成XML字符
        context.marshalDocument(order,CHARSET_NAME,null,writer);
        String xmlStr=writer.toString();
        writer.close();;
        System.out.println(xmlStr.toString());
        return xmlStr;
    }


    private Order decode2Order(String xmlBody) throws JiBXException {
        reader =new StringReader(xmlBody);
       
        IUnmarshallingContext context = factory.createUnmarshallingContext();
        // unmarshalDocument 将XML 字符解码为POJO实体
        Order order=(Order) context.unmarshalDocument(reader);
        return  order;
    }

    public static void main(String[] args) throws JiBXException, IOException {
        TestOrder testOrder=new TestOrder();
        Order order= OrderFactory.create(123);
        String body=testOrder.encode2Xml(order);
        Order order1=testOrder.decode2Order(body);
        System.out.println(order1);
    }

}

测试结果 如图:

在这里插入图片描述
说明 JiBX Unmarshal 数据分解 和 Marshal 数据编排 成功了。

错误解决

如果报缺少 JiBX_bindingList 。 说明之前的ant bind 命令执行没有成功。需要重新执行bind 命令。

Bug遗留

目前这个Order 实体里面有 Float ,String 和其他普通POJO 属性。 JiBX 是支持的。也是可用供大家学习实操的。
但是 不支持 集合属性和 枚举属性。
集合属性报 java.lang.String cannot be cast to org.jibx.runtime.IMarshallable 异常。 大家可以在Customer 给middleNames 属性赋值试下即可。
枚举属性报 该枚举没有可用的构造方法。大家可以将 Shipping 改为enum 试下。

如果有大神知道如何解决这两个问题,不胜感激。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158137.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C/C++ STL

常见容器性质总结 1.vector 底层数据结构为数组 &#xff0c;支持快速随机访问 2.list 底层数据结构为双向链表&#xff0c;支持快速增删 3.deque 底层数据结构为一个中央控制器和多个缓冲区&#xff0c;详细见STL源码剖析P146&#xff0c;支持首尾&#xff08;中间 不能&…

java mybatis的SpringBoot博客论坛管理系统

java mybatis的SpringBoot博客论坛管理系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式…

Java数据结构:堆与PriorityQueue优先级队列的使用

文章目录1 什么是堆2 堆的实现思路2.1 大根堆的成员变量简介2.2 树的相关知识复习2.3 向下调整创建大根堆2.4 堆的插入2.5 堆的删除3 大根堆实现代码及测试4 PriorityQueue的使用4.1 特性简介4.2 常用方法4.3 使用PriorityQueue实现大根堆写在最后1 什么是堆 堆实质上就是对完全…

python对称加密AES的使用

python对称加密AES的使用 aes安装 pip install pycryptodome加密库引用 from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES import base64完整代码 from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES import base64def A…

带你玩转OpenHarmony AI-基于海思NNIE的AI能力自定义

简介相信大家从玩转OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&#xff09;AI系列专题的其他文章中&#xff0c;已经拓展了OpenHarmony AI在智慧出行、智慧办公等多场景下的AI自动检测、识别和判断的新体验&#xff0c;对于OpenHarmony平台上的AI开发有了一定认识。…

通过事件总线EventBus/AsyncEventBus进行JAVA模块解耦 (史上最全)

事件总线在 进行JAVA模块解耦 &#xff0c;价值巨大 实际开发中&#xff0c;常常 通过事件总线EventBus/AsyncEventBus进行JAVA模块解耦 &#xff0c; 比如&#xff0c;在顶级开源组件 hotkey的源码中&#xff0c; 就多次用到 EventBus/AsyncEventBus进行JAVA模块解耦 所以&am…

71、AdaNeRF: Adaptive Sampling for Real-time Rendering of Neural Radiance Fields

简介 官网&#xff1a;https://thomasneff.github.io/adanerf/ 新的双网络架构&#xff0c;它采用正交方向&#xff0c;通过学习如何最好地减少所需样本点的数量&#xff0c;将网络分为联合训练的 sample 和 shading 网络&#xff0c;训练方案在每条射线上采用固定的样本位置…

Nginx 高级篇

文章目录Nginx 高级篇一、 负载均衡1、 负载均衡概述2、 处理方式2.1 用户手动选择2.2 DNS 轮询2.3 四 / 七层负载均衡3、 七层负载均衡3.1 七层负载均衡指令3.1.1 upstream3.1.2 server3.2 实现流程3.3 负载均衡的状态3.3.1 down3.3.2 backup3.3.3 max_conns3.3.4 max_fails &…

Docker前世今生

文章目录Docker背景Docker历史docker 理念Docker能做什么虚拟机的缺点容器虚拟化技术Docker学习途径Docker背景 一款产品从开发到上线&#xff0c;从操作系统&#xff0c;到运行环境&#xff0c;再到应用配置。作为开发运维之间的协作我们需要 关心很多东西&#xff0c;这也是…

ChatGPTAPI Key申请教程

ChatGPTAPI Key申请教程 一、API Key申请使用 在浏览器打开网址&#xff1a;https://openai.com/api/ 等待网页加载完成后&#xff0c;点击右上角 LOG IN 进入登录界面 进入登录界面后&#xff0c;依次输入注册的邮箱–Continue–输入密码–Continue&#xff0c;完成登录&…

< CSS小技巧:filter滤镜妙用>

文章目录&#x1f449; 前言&#x1f449; 简述&#x1f449; 基本语法及案例》语法简述》案例&#x1f449; 拓展1. drop-shadow 更加智能的阴影效果2. 网页置灰3. 元素强调、高亮4.节省空间&#xff0c;提高网页加载速度&#x1f449; 具体案例网页参考文献往期内容 &#x1…

如何有效进行团队建设:从关注事到关注人

咱打工人都想趁着年终总结这个契机&#xff0c;拿着工作数据跟领导们提涨薪&#xff01;但是入行没多久的社畜们却没有这个底气&#xff0c;虽累但没结果&#xff08;暗指身兼数职的项目经理小白们&#xff09;&#xff0c;主要是觉得自己的工作成绩不够优秀。这几天办公室的项…

Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks

摘要 我们为元学习提出了一个算法是模型无关model−agnosticmodel-agnosticmodel−agnostic. 在某种意义上&#xff0c;其与用梯度下降训练的模型是兼容的&#xff0c;可以应用在大量不同的学习问题上。包括&#xff1a;分类、回归、和加强学习。 元学习的目标是正在学习任务…

TAZ生成实践(Intel芯片Mac Python 3.7.9)

参考文章 https://blog.csdn.net/weixin_42632778/article/details/115164518 TAZ生成 https://zhuanlan.zhihu.com/p/343576683 使用ArcGIS实现线转栅格 https://pro.arcgis.com/zh-cn/pro-app/latest/tool-reference/conversion/polyline-to-raster.htm ArcGIS Pro 折线转栅格…

第②篇 Spring IoC——容器

Spring最成功的是其提出的理念&#xff0c;而不是技术本身。 概念 Spring所依赖的两个核心理念&#xff1a; 一个是控制反转&#xff08;IoC&#xff09;。另一个是面向切面编程&#xff08;Aspect Oriented Programming&#xff0c;AOP&#xff09;。 IoC是Spring的核心&am…

JS入门到精通详解(1)

JavaScript概述(需要记)什么是javascript?是一门&#xff08;基于对象&#xff09;和&#xff08;事件驱动&#xff09;的&#xff08;脚本语言&#xff09;。js诞生于哪一年&#xff1f;哪个公司&#xff1f;谁&#xff1f;第一个名字叫什么&#xff1f;1995年 网景 布兰登 l…

【Python】type、isinstance、issubclass详解

type type方法有两种重载形式&#xff1a; type(o: object)&#xff1b;type(name: str, bases:Tuple[type, ...], dict:Mapping[str: Any], **kwds) 使用第一种重载形式的时候&#xff0c;传入一个【object】类型&#xff0c;返回一个【type】对象&#xff0c;通常与object…

解决使用element-plus时使用el-select-v2组件时,选中后无法移除focus的状态的方法。

我们可以使用element-ui-plus的el-select-v2的组件&#xff0c;实现复合搜索和下拉框的功能。 使用如下模块&#xff1a; <template><el-select-v2 v-model"value" filterable :options"options" placeholder"Please select"visibleCha…

爸妈记性变差怎么办?

记不住事的时候&#xff0c;我们总会自嘲“老了&#xff0c;脑子不好使了”。记忆力总是和年龄挂钩的&#xff0c;所以很多子女听到父母这样说&#xff0c;也不会放在心上。但有时&#xff0c;记性变差不一定因为年龄&#xff0c;还有可能是患病的前兆。当父母出现频繁忘事的情…

zerotier虚拟网络配置,局域网与外网如同局域网一样访问。

zerotier:可以搭建用于自己的虚拟网络&#xff0c;经过授权连接成功之后彼此都在同一网段&#xff0c;可以像在局域网一样互相访问。 1.创建zerotier账户 2.创建网络&#xff08;Create A Network&#xff09;并记住网络标识&#xff08;NETWORK ID&#xff09; 一、openwrt设…