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 属性。

搞定收工!

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

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

相关文章

第91讲:MySQL主从复制集群主库与从库状态信息的含义

文章目录 1.主从复制集群正常状态信息2.从库状态信息中重要参数的含义 1.主从复制集群正常状态信息 通过以下命令查看主库的状态信息。 mysql> show processlist;在主库中查询当前数据库中的进程&#xff0c;看到Master has sent all binlog to slave; waiting for more u…

《WebKit 技术内幕》之六(3): CSS解释器和样式布局

3 WebKit布局 3.1 基础 当WebKit创建RenderObject对象之后&#xff0c;每个对象是不知道自己的位置、大小等信息的&#xff0c;WebKit根据框模型来计算它们的位置、大小等信息的过程称为布局计算&#xff08;或者称为排版&#xff09;。 图描述了这一过程中涉及的主要WebKit…

【解决方法】PPT不能编辑,按钮都是灰色,怎么办?

PPT文件打开之后&#xff0c;发现无法编辑&#xff0c;再仔细查看发现工具栏中的功能按钮都是灰色的&#xff0c;无法使用&#xff0c;这是什么原因&#xff1f;该如何解决&#xff1f; 原因&#xff1a;无法编辑PPT文件&#xff0c;并且功能按钮都是灰色&#xff0c;这是因为…

qnx 上screen + egl + opengles 最简实例

文章目录 前言一、qnx 上的窗口系统——screen二、screen + egl + opengles 最简实例1.使用 addvariant 命令创建工程目录2. 添加源码文件3. common.mk 文件4. 编译与执行总结参考资料前言 本文主要介绍如何在QNX 系统上使用egl和opengles 控制GPU渲染一个三角形并显示到屏幕上…

cuda中的定点数优化技术

这里学习一下定点数的优化操作&#xff0c;实际上就是以整数代替浮点数&#xff0c;乘除法的操作均通过左右移位来实现&#xff0c;适合在算力非常低的场景下使用&#xff0c;极致的压榨性能。 https://zhuanlan.zhihu.com/p/338588296 定点数介绍 以下给出函数的具体实现&…

纸黄金实战投资技巧:避免亏损的有效策略

在纸黄金交易的实战中&#xff0c;避免亏损是每位投资者都追求的目标。虽然任何投资都存在一定的风险&#xff0c;但采取一些有效的策略可以帮助投资者最大限度地减少亏损的可能性。以下是一些在纸黄金交易中避免亏损的实战技巧&#xff1a; 一、设定止损点是避免亏损的关键 止…

【Linux】

Linux零基础入门 列出文件/文件夹新建/切换路径查看当前路径重命名或者移动文件夹拷贝文件/文件夹删除文件夹设置环境变量编辑文本文件压缩和解压查看cpu的信息查看/杀死进程查看进程的CPU和内存占用重定向日志场景一场景二场景三场景四 列出文件/文件夹 命令&#xff1a;Ls(L…

All the stories begin at installation

Before installation, there are some key points about Conan: “Conan is a dependency and package manager for C and C languages.”“With full binary management, Conan can create and reuse any number of different binaries (for different configurations like a…

基于SpringBoot的智慧社区居家养老健康管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Kafka常见指令及监控程序介绍

kafka在流数据、IO削峰上非常有用&#xff0c;以下对于这款程序&#xff0c;做一些常见指令介绍。 下文使用–bootstrap-server 10.0.0.102:9092,10.0.0.103:9092,10.0.0.104:9092 需自行填写各自对应的集群IP和kafka的端口。 该写法 等同 –bootstrap-server localhost:9092 …

Unity 抽象工厂模式(实例详解)

文章目录 简介实例1实例2 简介 抽象工厂模式是一种创建型设计模式&#xff0c;它提供了一种方式来封装一组相关或相互依赖对象的创建过程&#xff0c;而无需指定具体类。这种模式常用于系统中有多组相关产品族&#xff0c;且客户端需要使用不同产品族中的对象时。 在Unity中&a…

Windows7关闭谷歌浏览器提示“若要接收后续 Google Chrome 更新,您需使用 Windows 10 或更高版本”的方法

背景 电脑比较老&#xff0c;系统一直没有更新&#xff0c;硬件和软件版本如下&#xff1a; 操作系统版本&#xff1a;Windows7 企业版 谷歌浏览器版本&#xff1a;109.0.5414.120&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; 该版本的谷歌浏览器是支持…

MySQL不同插入方式性能对比实验

最近负责的项目需要数据同步入库MySQL&#xff0c;为了测速那种入库方式效率比较高&#xff0c;为此进行了以下的对比实验&#xff0c;在此记录一下 实验表单数据格式 实验代码 共三种方法对比 mutiSqlInsert: 一条一条插入&#xff0c;最后一次提交 singleSqlInsert&…

LabVIEW滚动轴承故障在线监测

展示了如何将LabVIEW开发出一种有效的滚动轴承故障在线监测系统。介绍了该系统的开发过程、工作原理及其在实际应用中的效果。该系统成功地应用于对滚动轴承故障的早期诊断&#xff0c;提高了故障检测的准确性和效率。 滚动轴承在工作过程中会产生复杂的振动信号&#xff0c;包…

Proxmox VE 8 试装Oracle 23c

作者&#xff1a;田逸&#xff08;formyz&#xff09; Oracle 当前的最新版本是23c&#xff0c;虽然官方网站下载不了它的正式版本&#xff0c;但是却提供了一个性能受限的免费版本“Oracle Database 23.3 Free”&#xff08;存储容量受限、内存使用受限&#xff09;。这里就只…

[机缘参悟-129] :个人对人生之苦解决之道的思考

目录 前言&#xff1a; 第1层&#xff1a;环境层 1.1 环境的分类 1.2 理解环境的运作的基本原理 1.3 主动选择适合自己的愉快的环境 1.4 主动构建适合自己的愉快的环境 第2层&#xff1a;生理层 2.1 生理健康和情绪之间的关系 2.2 学习人的生物、生理、健康的基本知识…

MySQL与PostgreSQL对比

对比 许可证 License MySQL 社区版采用 GPL 许可证。Postgres 发布在 PostgreSQL 许可下&#xff0c;是一种类似于 BSD 或 MIT 的自由开源许可。 即便 MySQL 采用了 GPL&#xff0c;仍有人担心 MySQL 归 Oracle 所有&#xff0c;这也是为什么 MariaDB 从 MySQL 分叉出来。 …

数据出境——电商API接口使得电商数据跨境流动已成为趋势

在数字经济的当下&#xff0c;数据已经成为商业决策的关键因素。尤其是电商领域&#xff0c;电商API数据采集不仅关乎企业运营效率&#xff0c;还涉及到用户隐私与国家安全。近年来&#xff0c;随着电商市场的全球化发展&#xff0c;电商数据出境与跨境贸易已成为不可逆转的趋势…

vue3-模版引用ref

1. 介绍 概念&#xff1a;通过 ref标识 获取真实的 dom对象或者组件实例对象 2. 基本使用 实现步骤&#xff1a; 调用ref函数生成一个ref对象 通过ref标识绑定ref对象到标签 代码如下&#xff1a; 父组件&#xff1a; <script setup> import { onMounted, ref } …

Android Studio 之 菜单 Menu

选项菜单 OptionsMenu 用xml添加&#xff08;更建议使用&#xff09; 创建一个菜单布局 : 在 res文件下新建一个menu 目录&#xff0c;此时的菜单id为&#xff1a;R.menu.option <?xml version"1.0" encoding"utf-8"?> <menu xmlns:android&…