Spring boot项目java bean和xml互转

Spring boot项目实现java bean和xml互转

  • 项目场景:
  • 互转方法
    • 使用`jackson`进行互转
    • 使用`jaxws`进行`xml`与`bean`的互转
  • 搞定收工!

项目场景:

工作中需要给下游第三方收费系统做数据挡板,由于下游系统使用的是soap webservice,里面涉及各种xml跟bean的互转,在此介绍一下使用的方法。
基于springboot搭建webservice的过程将会在下篇博客介绍


互转方法

这里介绍两种方法.

  • 使用jackson进行互转,Spring boot项目自带的jsonbean的互转的框架,他其实还有xmlbean的互转。
  • 使用jaxws进行xmlbean的互转

使用jackson进行互转

因为Spring Boot 项目其他依赖基本上都会引入,只是缺少一个依赖com.fasterxml.jackson.dataformat:jackson-dataformat-xml,所以只需要引入这一个依赖即可。

  • gradle引入
implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-xml')
  • maven 引入
		<dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.13.5</version>
        </dependency>
  • 可以做成一个通用的XMLUtils工具类,代码如下:
	public static String javaBean2Xml(Object javaBean) throws JsonProcessingException {
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.setDefaultUseWrapper(false);
        //字段为null就自动忽略,不再序列化
        xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //XML标签名:使用骆驼命名的属性名,
        xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
        //设置转换模式,就是根据getter、setter方法,设置为第一个字母小写这种
        xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
        return xmlMapper.writeValueAsString(javaBean);
    }

    public static <T> T Xml2javaBean(String javaBean, Class<T> tClass) throws JsonProcessingException {

            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.setDefaultUseWrapper(false);
            //字段为null,自动忽略,不再序列化
            xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            //XML标签名:使用骆驼命名的属性名,
            xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);
            //设置转换模式,就是根据getter、setter方法,设置为第一个字母小写这种
            xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
            return xmlMapper.readValue(javaBean, tClass);
    }
  • POJO类,后续都会用这个做例子
public class Student {
    private String name;
    private String teacher;
    private Integer age;
    ....省略构造函数和getter和setter
}
  • 测试案例
public static void main(String[] args) throws JsonProcessingException {
    Student student = new Student("张三","张老师", 26);
    String s = XMLUtils.javaBean2Xml(student);
    System.out.println(s);
    System.out.println(XMLUtils.Xml2javaBean(s, Student.class));
}

结果:
在这里插入图片描述

  • 可能会出现的bug

在使用jackson去进行转换的时候,POJO类不管几个构造函数,一定要有无参构造,否则就会报错。
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of Student (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

  • 如果想给POJO的属性的XML起个别名怎么办,jackson是提供了相关的注解。
  • @JacksonXmlRootElement
    namespace属性:用于指定XML根元素命名空间的名称。
    localname属性:用于指定XML根元素节点标签的名称。
  • @JacksonXmlProperty
    namespace和localname属性用于指定XML命名空间的名称,isAttribute指定该属 性作为XML的属性()还是作为子标签().
  • @JacksonXmlText注解将属性直接作为未被标签包裹的普通文本。
  • @JacksonXmlCData将属性包裹在CDATA标签中。
  • 集合元素的映射
    @JacksonXmlElementWrapper可以将列表数据转为XML节点。
    useWrapping属性设置是否设置外围标签名,默认true

其他的可以自己尝试下,如果是List的集合的,是以一对多的一对应的,一里面定义了XML节点,就以一里面的定义为主。

  • 补充完整的依赖,和Spring Boot已经引入的依赖。

    • 完整依赖
      <dependency>
          <groupId>com.fasterxml.jackson.dataformat</groupId>
          <artifactId>jackson-dataformat-xml</artifactId>
          <version>2.13.5</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.13.5</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.13.5</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.13.5</version>
      </dependency>
      
    • Spring Boot已经引入的依赖,以2.6.12为例
      在这里插入图片描述

使用jaxws进行xmlbean的互转

使用起来基本是跟jackson差不多的。好处就是jdk自己就有提供,不需要引入额外的工具包,主要是使用javax下的 JAXBContext 接口,利用MarshallerUnmarshaller接口来进行xmlbean的互转。
但是需要注意的是

  • 必须要提供无参构造器,否则会报错com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Student没有无参数默认构造器。
  • 必须在类上提供@javax.xml.bind.annotation.XmlRootElement,否则会报错javax.xml.bind.MarshalException
    -with linked exception:
    [com.sun.istack.SAXException2: 由于类型 “Student” 缺少 @XmlRootElement 注释, 无法将该类型编集为元素]
  • 如果不提供@javax.xml.bind.annotation.XmlElement注解,那么所产生的XML节点均为属性值,就是小写。
  • @javax.xml.bind.annotation.XmlElement定义的值不能跟getter方法一起出现,否则会报错com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
    类的两个属性具有相同名称 “name”
  • 老规矩,工具类
	public static String beanToXml (Object obj, Class<?> zlass) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(zlass);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        StringWriter writer = new StringWriter();
        marshaller.marshal(obj,writer);
        return writer.toString();
    }
    public static <T> T xmlToBean (String xml, Class<T> zlass) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(zlass);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        Object object = unmarshaller.unmarshal(new StringReader(xml));
        return (T) object;
    }
  • Marshaller 接口中还定义了5个属性,分别是:
  • JAXB_ENCODING
    这个属性是设置编码集,
    marshaller.setProperty(Marshaller.JAXB_ENCODING, “GBK”);
  • JAXB_FORMATTED_OUTPUT
    这个属性是是否格式化生成的xml串 true-格式化,false-不格式化
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  • JAXB_SCHEMA_LOCATION
    指定xsi:schemaLocation,它定义了XML Namespace和对应的XSD(Xml Schema Definition)文档的位置的关系。它的值由一个或多个URI引用对组成,两个URI之间以空白符分隔(空格和换行均可)。第一个URI是定义的XML Namespace的值,第二个URI给出Schema文档的位置,Schema处理器将从这个位置读取Schema文档,该文档的targetNamespace必须与第一个URI相匹配。
    marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, “xxx.xxx.xxx”);
  • JAXB_NO_NAMESPACE_SCHEMA_LOCATION
    如果没有Namespeace,但是需要使用Schema,就需要用到JAXB_NO_NAMESPACE_SCHEMA_LOCATION,它可以指定将放置在已编组 XML 输出中的 xsi:noNamespaceSchemaLocation 属性值
    marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, “xxx.xxx.xxx”);
  • JAXB_FRAGMENT
    是否省略xml头信息()true-省略,false-不省略
    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
  • 代码
public static void main(String[] args) throws Exception {
    Student student = new Student("张三","张老师", 26);
    String s = XMLUtils.beanToXml(student, Student.class);
    System.out.println(s);
    System.out.println(XMLUtils.xmlToBean(s, Student.class));
}
  • 测试
    在这里插入图片描述
  • 最后补充几个注解
  • @XmlRootElement
    类级别的注解,这个注解为根节点的注解,加在类上面,而且为必要的注解,如果没有此注解,执行beanToXml方法时将会报异常。这个根节点默认名字为类名,但是可以设置name属性来修改根节点名字。namespace属性可以用于指定生成的元素所属的命名空间。
  • @XmlElement
    字段,方法级别的注解,将java类的属性映射为xml的一个结点。一般使用在属性上,或者get方法上,其中常用的属性有name、nillable、namespace、defaultValue。name可以设置结点的名称;nillable 指定文本是否可以为空,true-可以为空,false-不可以为空,默认为false,如果设置为true,则该字段为空是,这个结点也会生成,但是值为空,如果是指为false,则该结点不生成;namespace属性可以用于指定生成的元素所属的命名空间;defaultValue 可以设置该结点的默认文本。
  • @XmlTransient
    类,字段,方法级别的注解。当添加这个注解后,这个属性或者类将不进行映射。需要注意的是该注解与所有其他JAXB注解相互排斥.
  • @XmlAccessorType
    类级别注解,其中有一个value属性,值为XmlAccessType的枚举类。
    1.XmlAccessType.PROPERTY 加这个value表示,会将所有拥有get方法和set方法的属性(必须2个方法都有,否则不映射)映射成xml,除非加入@XmlTransient则不会映射,如果没有get/set方法,则需要再属性上加上@XmlElement。
    2.XmlAccessType.FIELD
    这个属性是将类中非静态的属性都映射到xml中,并且不需要加get/set方法
    3.XmlAccessType.PUBLIC_MEMBER
    这个属性值,是@XmlAccessorType的默认默认值,它会将属性为public的属性或者get/set方法同时为public的属性映射成xml。
    4.XmlAccessType.NONE
    这个属性表示任何属性都不会被映射到xml中,除非使用其他注解,如@XmlElement
  • @XmlAccessorOrder
    类级别的注解。控制生成属性映射xml结点的顺序。其中有一个value属性,可以设置排序方式,XmlAccessOrder.ALPHABETICAL 为按照字母顺序进行排序, XmlAccessOrder.UNDEFINED按照属性顺序进行排序,默认为XmlAccessOrder.UNDEFINED
  • @XmlJavaTypeAdapter
    这个注解主要是解决一些数据格式化问题的,比如时间格式化。
  • @XmlElementWrapper
    这个注解是加在集合上面的
  • @XmlAttribute
    这个注解会将属性变为上一个结点的属性
  • @XmlType
    类级别的注解,这个注解可以自定义排序,使用propOrder 属性。

搞定收工!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django笔记(一):环境部署

目录 Python虚拟环境 安装virtualenv 创建环境 激活环境 关闭&#xff1a; 安装Django VSCode配置 Python插件 Django插件 解释器选择 Django部署 创建项目 创建app 创建模板 编写视图 编写路由 启动服务器 访问 Python虚拟环境 安装virtualenv pip i…

低代码助力制造业数智转型,激发创新力迎接工业 4.0

随着科技的不断进步&#xff0c;我们迈入了一个崭新的工业时代——工业4.0。这场工业革命不仅颠覆了制造业的传统形象&#xff0c;还为全球生产方式带来了前所未有的变革。 在这一过程中&#xff0c;制造业数字化转型逐渐成为主旋律&#xff0c;而低代码技术在这其中发挥着重要…

网上订货管理系统功能列表|企业手机订单管理软件

网上订货管理系统功能列表|企业手机订单管理软件 后台功能列表 &#xff08;后台支持手机版本 订货APP,管理订单的APP&#xff09; 后台登陆 输入账号密码登录企业订货管理软件系统 后台首页 显示近日,月,年订单统计&#xff0c;和收款欠款等统计。 订单模块 新建订单 &am…

Java:选择哪个Java IDE好?

Java&#xff1a;选择哪个Java IDE好? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&…

空气制水机市场调研:预计2029年将达到5.2亿美元

空气制水机&#xff0c;是一种通过高效过滤空气中的水分子冷凝成为液态水&#xff0c;再通过一系列净化处理方法生产出高品质饮用水的设备。也就是说&#xff0c;它靠空气温度和湿度驱动取水&#xff0c;经过几层空气过滤和水路过滤&#xff0c;制造出安全健康的直饮水&#xf…

电力能源三维可视化合集 | 图扑数字孪生

电力能源是现代社会发展和运行的基石&#xff0c;渗透于工业、商业、农业、家庭生活等方方面面&#xff0c;它为经济、生活质量、环境保护和社会发展提供了巨大的机会和潜力。图扑软件应用自研 HT for Web 强大的渲染引擎&#xff0c;助力现代化的电力能源数字孪生场景&#xf…

RHCE9学习指南 第22章 用rpm管理软件

rpm全称是redhat package manager&#xff0c;后来改成rpm package manager&#xff0c;这是根据源码包编译出来的包。先从光盘中拷贝一个包&#xff0c;并看他是如何命名的。 先挂载光盘&#xff0c;然后拷贝vsftpd这个包&#xff0c;命令如下。 [rootserver ~]# mount /dev/…

如何绘制出图像的色素分布直方图

效果 如图&#xff0c;可以展示出我们的图像的颜色分布直方图,表明的图像的亮和暗 实现可视化色素分布直方图方法 这里我们对我们的灰色图片和彩色图片进行了直方图显示 import cv2 import matplotlib.pyplot as plt image cv2.imread("test.jpg") # 彩色图片->…

【leetcode 2171. 拿出最少数目的魔法豆】没有数学,全是思路

2171. 拿出最少数目的魔法豆 题目描述 给定一个 正整数 数组 beans &#xff0c;其中每个整数表示一个袋子里装的魔法豆的数目。 请你从每个袋子中 拿出 一些豆子&#xff08;也可以 不拿出&#xff09;&#xff0c;使得剩下的 非空 袋子中&#xff08;即 至少还有一颗 魔法豆…

鼠害监测站的意义是什么

鼠害监测站是专门用于监测鼠害发生情况、种群结构和危害程度的设施。这些站点通常设立在农田、森林、草原等鼠害易发区域&#xff0c;通过定期调查和监测&#xff0c;收集鼠害相关信息&#xff0c;为防治工作提供科学依据。 TH-SH1 鼠害监测站的意义 保障农业生产&#xff1a;…

精品基于Uniapp+springboot美食菜谱类管理系统APP

《[含文档PPT源码等]精品基于Uniappspringboot美食类管理系统APP》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 后台框架&#xff1a;springboot、ssm 安…

SpringBoot中整合MybatisPlus快速实现Mysql增删改查和条件构造器

场景 Mybatis-Plus(简称MP)是一个Mybatis的增强工具&#xff0c;只是在Mybatis的基础上做了增强却不做改变&#xff0c;MyBatis-Plus支持所有Mybatis原生的特性&#xff0c; 所以引入Mybatis-Plus不会对现有的Mybatis构架产生任何影响。MyBatis 增强工具包&#xff0c;简化 C…

掌握退款与测评自养号技术,在亚马逊、沃尔玛上轻松做卖家

今天&#xff0c;我想与大家分享在亚马逊、沃尔玛退款自养号中的一些经验。众所周知&#xff0c;自养号的环境是至关重要的&#xff0c;它涉及到系统的纯净度、下单所用的信用卡以及许多其他细节。一个良好的养号环境能够确保账号的安全与稳定&#xff0c;进而提高退款成功率。…

2023年暴涨130%后,嘉年华游轮股价2024年还会继续暴涨吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 2023年对嘉年华游轮来说的标志性的一年 2023年&#xff0c;嘉年华游轮(CCL)的业务不但实现了全面复苏&#xff0c;而且其股价也重新回到了市场领先地位&#xff0c;全年上涨了130%&#xff0c;远远超过了标普500指数24%的涨…

数据库结构、数据对比及同步

目录 一、场景二、操作Navicat Premium 一、场景 部署服务时需要确保开发环境的数据库与生产环境的数据库结构、数据一致 这时可以通过Navicat Premium、SQLyog等工具进行数据库对比 二、操作 Navicat Premium 1、选择同步类型 2、选择对比的数据库 3、选择对比参数 4、查看…

预处理详解(#和##运算符、命名约定、#undef​​、命令行定义​、条件编译、头文件的包含​)

目录 一、#和## 1.1#运算符 1.2## 运算符​ 二、命名约定​ 三、#undef​ 四、命令行定义​ 五、条件编译​ 六、头文件的包含​ 4.1 头文件被包含的方式&#xff1a;​ 4.1.1 本地文件包含​ Linux环境的标准头文件的路径&#xff1a;​ VS环境的标准头文件的路径&…

HelloWorld(java)

1.切换盘符&#xff1a;找到刚刚书写的代码 2.编译&#xff1a;javac是JDK提供的编译工具&#xff0c;通过这个工具&#xff0c;把当前路径下下的HelloWorld.java文件编译成class文件 3.运行&#xff1a;java也是JDK提供的一个工具&#xff0c;作用就是用来运行代码&#xff…

【漏洞复现】银达汇智智慧综合管理平台任意文件读取漏洞

Nx01 产品简介 福建银达汇智信息科技股份有限公司成立于2009年&#xff0c;位于福建省福州市&#xff0c;是一家以从事软件和信息技术服务业为主的企业。 Nx02 漏洞描述 银达汇智智慧综合管理平台 FileDownLoad.aspx 存在任意文件读取漏洞&#xff0c;通过漏洞攻击者可下载服务…

项目管理十大知识领域之成本管理

1. 项目成本管理的意义和重要性 项目成本管理是项目管理中至关重要的一部分&#xff0c;它直接关系到项目最终成本和利润的控制&#xff0c;对于企业的可持续发展具有重要意义。通过合理的成本管理&#xff0c;项目能够更好地控制预算&#xff0c;提高效率&#xff0c;降低成本…

计算机系统基础知识一、数值的源码、反码、补码、移码

目录 一、原码、反码、补码定义 1、原码表示 2、反码表示 3、补码表示 二、算数运算 1、二进制算数运算规则 2、机器数的加减运算 三、移码定义 四、移码的意义 概要 在计算机基础中&#xff0c;原码、反码、补码和移码是用于表示和处理有符号整数的编码方式。它们…