xml与实体之间的转换

2023-05-16

在对接一些第三方接口的时候往往需要涉及到一些对xml文件的处理,小编今天主要总结一下JavaBean与xml文件之间互相转换的探索与实例

使用JAXB技术实现xml与实体之间的转换

1. 是什么:

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。

2. 常用注解
@XmlRootElement:用于类级别的注解,对应xml的跟元素。通过name属性定义这个根节点的名称。
@XmlAccessorType:定义映射这个类中的何种类型都需要映射到xml(控制字段或属性的序列化)

XmlAccessorType的几种类型说明:
1. XmlAccessType.PUBLIC_MEMBER(默认):java对象中所有的public访问权限的成员变量和通过getter/setter方式访问的成员变量。
2. XmlAccessType.FIELD: java对象中的所有成员变量
3. XmlAccessType.PROPERTY:java对象中所有通过getter/setter方式访问的成员变量。(除非用@XmlTransient注释)
4. XmlAccessType.NONE: java对象的所有属性都不映射为xml的元素。

@XmlAttribute:用于把java对象的属性映射为xml的属性,并可通过name属性为生成的xml属性指定别名。
@XmlElement:指定一个字段或get/set方法映射到xml的节点。通过name属性定义这个根节点的名称。
@XmlElementWrapper,为数组或集合定义一个父节点。通过name属性定义这个父节点的名称。
@XmlTransient:它会为它的target阻止绑定操作,这个target可以是一个class或者一个field或者一个method。如果你遇到了从public field导致的名字冲突(拿foo来说,getFoo和setFoo),那么使用这个注解将会是很有用的
@XmlJavaTypeAdapter:使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML(可以应用于对<![CDATA[]]数据的处理)

3.应用实例

  1. 相关工具类:
/**
     * beanToXml工具类
     * @param obj 待转化实体
     * @param load 带有xml元素的实体类
     * @param encoding 编码格式
     * @return
     * @throws JAXBException
     */
public static String beanToXml(Object obj, Class<?> load, String encoding) throws JAXBException {
        if (encoding == null || encoding.isEmpty()) {
            encoding = "UTF-8";
        }
        JAXBContext context = JAXBContext.newInstance(load);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//格式化
        marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);//设置编码
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

        //防止<![CDATA[]] 转义
        marshaller.setProperty(CharacterEscapeHandler.class.getName(),
                (CharacterEscapeHandler)(chars, start, length, isAttVal, writer) -> writer.write(chars, start, length));

        StringWriter writer = new StringWriter();

        //添加表头
        writer.write("<?xml version=\'1.0\' encoding=\'" + encoding + "\'?>\n");
        marshaller.marshal(obj, writer);
        return writer.toString();
    }
/**
     * xml转bean工具类
     * @param xml string类型的xml串
     * @param <T> 目标实体类
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T converyToJavaBean(String xml, Class<T> c) {
        T t = null;
        try {
            JAXBContext context = JAXBContext.newInstance(c);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return t;
    }
/**
 * 扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML
 * 此处目的在于对<![CDATA[]]>的数据进行包装和解析
 */
public class CDataAdapter extends XmlAdapter<String, String>
{
    @Override
    public String marshal (String v) throws Exception
    {
        if(v==null||v.isEmpty()){
            return v;
        }
        return new StringBuilder("<![CDATA[").append(v).append("]]>").toString();
    }
    @Override
    public String unmarshal (String v) throws Exception
    {
        if ("<![CDATA[]]>".equals (v))
        {
            return "";
        }
        String v1 = null;
        String v2 = null;
        String subStart = "<![CDATA[";
        int a = v.indexOf (subStart);
        if (a >= 0)
        {
            v1 = v.substring (subStart.length (), v.length ());
        }
        else
        {
            return v;
        }
        String subEnd = "]]>";
        int b = v1.indexOf (subEnd);
        if (b >= 0)
        {
            v2 = v1.substring (0, b);
        }
        return v2;
    }

}
  1. 相关实体定义:
@Data
@XmlRootElement(name="OrderList")
@XmlAccessorType(XmlAccessType.FIELD)
public class OrderDTO {

    @XmlElement(name="orderNumber")
    private String orderNo;

    @XmlElement(name="customerName")
    private String customerName;

    @XmlElementWrapper(name="items")
    @XmlElement(name="item")
    private List<OrderItemDTO> orderItemDTOList;
}

@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class OrderItemDTO {
    
    @XmlJavaTypeAdapter(CDataAdapter.class)
    @XmlElement(name="Title")
    private String productName;
    
    @XmlElement(name = "Number")
    private Integer productNumber;
}
  1. 以Test的形式展示一下执行效果
public class SerializeXmlTest {

    private OrderDTO orderDTO=new OrderDTO();
    private List<OrderItemDTO> orderItemDTOList=new ArrayList<>();
    @Before
    public void init(){
        orderDTO.setOrderNo("1231");
        orderDTO.setCustomerName("test");
        OrderItemDTO orderItemDTO=new OrderItemDTO();
        orderItemDTO.setProductName("spu1");
        orderItemDTO.setProductNumber(2);
        orderItemDTOList.add(orderItemDTO);
        orderDTO.setOrderItemDTOList(orderItemDTOList);
    }

    @Test
    public void xmlToBean() throws JAXBException {
        String xml=XMLUtils.beanToXml(orderDTO,OrderDTO.class,null);
        System.out.println("转xml:\n".concat(xml));
    }

    @Test
    public void beanToXml(){
        String xml="<?xml version='1.0' encoding='UTF-8'?>\n" +
                "<OrderList>\n" +
                "    <orderNumber>1231</orderNumber>\n" +
                "    <customerName>test</customerName>\n" +
                "    <items>\n" +
                "        <item>\n" +
                "            <Title><![CDATA[spu1]]></Title>\n" +
                "            <Number>2</Number>\n" +
                "        </item>\n" +
                "    </items>\n" +
                "</OrderList>";
        OrderDTO orderDTO=XMLUtils.converyToJavaBean(xml,OrderDTO.class);
        System.out.println("转实体:\n"+JSONUtils.toJSONString(orderDTO));
    }
}

4.结果展示:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

xml与实体之间的转换 的相关文章

随机推荐

  • 【Qt线程-4】事件循环嵌套,BlockingQueuedConnection与QWaitCondition比较

    背景 xff1a 个人学习多线程控制 xff0c 写了一些博文用于记录 xff1a Qt线程 1 this xff0c volatile xff0c exec xff0c moveToThread Qt线程 2 事件循环 xff08 QCo
  • 【Qt样式(qss)-3】几套配色方案

    背景 xff1a 之前写过有关qss的博客 xff0c 记录了如何使用qt手册 xff0c 以及在项目中如何使用qss的体验 经过实践 xff0c 我归纳了自己需要的qss使用方法 xff0c 使之尽量高效 xff0c 容易维护 Qt样式
  • 【Qt样式(qss)-4】应用到QMdiArea不生效的解决

    背景 xff1a 之前写记录过几篇qss相关内容 xff1a Qt样式 xff08 qss xff09 1 手册小结 xff08 附例 xff1a 软件深色模式 xff09 Qt样式 xff08 qss xff09 2 使用小结 xff08
  • Google play billing(Google play 内支付) 下篇

    开篇 xff1a 如billing开发文档所说 xff0c 要在你的应用中实现In app Billing只需要完成以下几步就可以了 第一 把你上篇下载的AIDL文件添加到你的工程里 xff0c 第二 把 lt uses permissio
  • Qt creator中操作QAction加入QToolBar

    背景 xff1a 个人笔记 我之前没有系统化学习过任何资料 xff0c 使用很多工具都是按需出发 xff0c 直接上手 xff0c 遇到问题再研究的 所以会有一些弯路 本文言语中难免有对个人情绪的生动描述 xff0c 希望不要影响读者心情
  • Java 通过map构造树形结构

    在开发中 xff0c 经常会有将 数据组装成为树形结构的场景 xff0c 除了可以通过递归实现 xff0c 还可以通过map 组装实现 一 xff0c 构造基本数据 import apple laf JRSUIUtils import co
  • 【无标题】es搜索基本操作

    一 xff0c 准备数据 1 创建索引 PUT lagou book 2 创建mapping PUT lagou book doc mapping 34 properties 34 34 description 34 34 type 34
  • 【ES】常用操作工具

    工欲善其事 xff0c 必先利于器 xff0c es使用过程中 xff0c 有些工具能帮助我们快速的上手和使用 一 es head es head 是一款专门针对 es的客户端工具elasticSearch配置包 是一个基于node js的
  • 【es】基本概念理解

    一 xff0c 初识es 1 是什么 xff1f ElasticSearch 简称es 开源的分布式的全文搜索引擎 xff0c 可以近乎实时的存储检索数据 xff0c es使用java开发 xff0c 并且使用Lucene作为核心实现搜索功
  • 无法安装net framework 3.5 的解决方法

    电脑刚重装了Windows8 1系统 xff0c 然后安装数据库的时候 xff0c 却出现了这样的问题 xff1a 您的电脑上的应用需要使用以下windows功能 问题原因是 xff1a 在安装系统的时候 xff0c NET Framewo
  • 【计算机网络原理】第四章 数据链路层

    今天主要梳理了一下数据链路层的内容 xff0c 如下 一 宏观规划 综合数据链路层的整体 xff0c 分为两大部分 xff0c 第一部分讲解数据链路层的功能 xff0c 第二部分讲解数据链路层的功能 这些协议 xff0c 其实还是为了实现数
  • 【redis】关系型数据库 VS 非关系型数据库

    一 关系型数据库 xff1f 1 概念 关系型数据库是指采用了关系模型来组织数据的数据库 简单来说 xff0c 关系模式就是二维表格模型 主要代表 xff1a SQL Server xff0c Oracle Mysql PostgreSQL
  • resultful风格接口

    一 产生背景 网络应用程序 xff0c 越来越流行前端和后端的分离设计 当前的发展趋势是前端的设计层出不穷 比如 xff1a 各种型号的手机 平板灯其他设计 因为必须要一种统一的机制方便不同的前端和后端进行通信 这就导致了API结构的流行
  • 【kafka】Exception thrown when sending a message with key='null' and payload='lizhenjuan;99' to topic

    今天碰到一个奇怪的问题 xff0c 如下图 xff1a 一 问题 1 问题截图 上午还可以发送消息成功的 xff0c 下午突然就发送不了消息了 我就检查我代码的问题 xff0c 是传递的格式不对 xff0c 还是数据要求不对 网上的资料显示
  • 【0723】自动化运维——saltstack

    24 1 自动化运维介绍 认识自动化运维 xff1a 传统运维效率低 xff0c 大多工作人为完成传统运维工作繁琐 xff0c 容易出错传统运维每日重复做相同的事情传统运维没有标准化流程传统运维的脚本繁多 xff0c 不能方便管理自动化运维
  • 【mysql】order by多个字段排序

    今天遇到了两个字段排序的问题 xff0c 感觉不是很清晰 xff0c 所有又按照规则查询了下 xff0c 总结下 count都是306的有三个 现在需要同时按照age和count排序 xff0c 测试最后的排序结果 默认都是按照age和co
  • java8使用积累

    1 将List lt T gt 数组转换为String并用逗号隔开 String join 34 34 List 2 idea自动补全代码教程 xff1a https www cnblogs com HF Made p 11417225 h
  • 【java】手动分页工具类

    最近小编遇到一个很绕的问题 xff0c 无法使用mybatis自带的分页插件对符合条件的数据进行分页 xff0c 故收集了一个自动分页的工具类 xff1a public static lt T gt List lt T gt getPage
  • redis 使用bitMap实现统计系统在线用户数量

    BitMap xff0c 简单来说 xff0c 其实也就是 byte 数组 xff0c 用二进制表示 xff0c 一个bit的值 xff0c 或者是0 xff0c 或者是1 xff1b 也就是说一个bit能存储的最多信息是2 它用一个bit
  • xml与实体之间的转换

    在对接一些第三方接口的时候往往需要涉及到一些对xml文件的处理 xff0c 小编今天主要总结一下JavaBean与xml文件之间互相转换的探索与实例 使用JAXB技术实现xml与实体之间的转换 1 是什么 xff1a JAXB xff08