XML序列化和反序列化的学习
1、基本介绍
在工作中,经常为了调通上游接口,从而对请求第三方的参数进行XML序列化,这里常使用的方式就是使用JAVA扩展包中的相关注解和类来实现xml的序列化和反序列化。
2、自定义工具类
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.concurrent.ConcurrentHashMap;/*** 1、实现 对象 转 xml* 2、实现 xml 转对象*/
public class XmlInterfaceUtils {private static final ConcurrentHashMap<Class<?>, JAXBContext> contextMap =new ConcurrentHashMap<>();private static JAXBContext context(Class<?> clazz) {// JAXBContext 是线程安全的,可以在多个线程中复用// computeIfAbsent 方法,如果map集合存在相同的key,则覆盖value值;不存在相同key,则添加到map集合中return contextMap.computeIfAbsent(clazz, cls -> {try {return JAXBContext.newInstance(cls);} catch (JAXBException e) {throw new IllegalStateException(e);}});}public static String convertToXml(Object obj) {StringWriter sw = new StringWriter();JAXBContext context = context(obj.getClass());Marshaller marshaller;try {marshaller = context.createMarshaller();//1.格式化输出,即按标签自动换行,否则就是一行输出marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);//2.设置编码(默认编码就是utf-8)
// marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");//3.是否省略xml头信息,默认不省略(false)// <?xml version="1.0" encoding="UTF-8"> 这一句就是"头信息"
// marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);marshaller.marshal(obj, sw);} catch (JAXBException e) {throw new IllegalStateException(e);}return sw.toString();}/*** xml转object** @param clazz 转换类* @param xml XML 字符串* @param <T> 对象类型* @return 转换结果*/public static <T> T xmlToObject(Class<T> clazz, String xml) {JAXBContext context = context(clazz);// 每次都创建 UnmarshallerUnmarshaller unmarshaller;try {unmarshaller = context.createUnmarshaller();} catch (JAXBException e) {throw new IllegalStateException(e);}StringReader reader = new StringReader(xml);T message;try {message = (T) unmarshaller.unmarshal(reader);} catch (JAXBException e) {throw new IllegalStateException(e);}return message;}
}
3、模拟请求第三方的请求参数-V1.0
3.1 定义业务实体
Provider类
import javax.xml.bind.annotation.*;@XmlRootElement
public class Provider {private User user;private String id;private Integer providerTelephone;private String providerAddress;public String getId() {return id;}public void setId(String id) {this.id = id;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}public Integer getProviderTelephone() {return providerTelephone;}public void setProviderTelephone(Integer providerTelephone) {this.providerTelephone = providerTelephone;}public String getProviderAddress() {return providerAddress;}public void setProviderAddress(String providerAddress) {this.providerAddress = providerAddress;}
}
User类
public class User {private String username;private String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
3.2 运行代码
public class Application {public static void main(String[] args) {Provider provider = new Provider();User user = new User();user.setUsername("hu");user.setPassword("123456");provider.setUser(user);provider.setProviderTelephone(4008123);provider.setProviderAddress("BeiJing");provider.setId("No.1");//序列化成xml格式的字符串String xml = XmlInterfaceUtils.convertToXml(provider);System.out.println(xml);//反序列化成对象Provider provider1 = XmlInterfaceUtils.xmlToObject(Provider.class, xml);}
}
控制台打印结果

必须要有一个@XmlRootElement用来标记哪个类作为根节点。否则,反序列化会失败,提示缺少 @XmlRootElement注解。
4、模拟请求第三方的请求参数-V2.0
假如第三方发生改变,要求我们进行适配。
将Provider类原本的id标签设置为根节点的属性,其他标签全部首字母大写,且按照手机号码,地址,用户信息的顺序进行反序列化,而User类的标签仍然是小写开头。
mport javax.xml.bind.annotation.*;@XmlType(//指定序列化的时候,生成每个标签的顺序,不指定的话,默认按照从上到下的顺序生成propOrder = {"providerTelephone", "providerAddress", "user","id"}
)
@XmlRootElement(name = "Provider")
@XmlAccessorType(XmlAccessType.FIELD)
public class Provider {@XmlElement(name = "User")private User user;//该字段映射为一个属性@XmlAttribute(name = "id")private String id;@XmlElement(name = "ProviderTelephone")private Integer providerTelephone;@XmlElement(name = "ProviderAddress")private String providerAddress;public String getId() {return id;}public void setId(String id) {this.id = id;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}public Integer getProviderTelephone() {return providerTelephone;}public void setProviderTelephone(Integer providerTelephone) {this.providerTelephone = providerTelephone;}public String getProviderAddress() {return providerAddress;}public void setProviderAddress(String providerAddress) {this.providerAddress = providerAddress;}
}
运行结果如下

5、@XmlAccessorType的作用
通过上面的例子可以发现,@XmlElement注解用来是生成子节点,@XmlAttribute注解用来生成节点的属性。
那@XmlAccessorType注解的作用呢?
默认序列化的时候,会根据类的get()方法生成一个子节点或者是属性,但是,我在字段名上又用@XmlElement标记了,这也会生出一个子节点。两个相同的子节点名称,就会导致反序列化失败。

因此,就需要用【 @XmlAccessorType(XmlAccessType.FIELD) 】来直接对类的字段进行映射,不考虑get方法,这样就会正常序列化。
相关文章:
XML序列化和反序列化的学习
1、基本介绍 在工作中,经常为了调通上游接口,从而对请求第三方的参数进行XML序列化,这里常使用的方式就是使用JAVA扩展包中的相关注解和类来实现xml的序列化和反序列化。 2、自定义工具类 import javax.xml.bind.JAXBContext; import javax.x…...
npm ERR! code CERT_HAS_EXPIRED
很不幸看到这个提示。 查了很多网上的解决方案,都提到一个解决方案: npm install -g npmlatest 靠就是执行install报的错,你要我通过install来解决这个问题。可见大多数人都是转发,从不自己试试。 第二个是看系统时间。这个基…...
30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <5> 5分钟集成好caffeine并使用注解操作缓存
快速导航 <1> 5分钟快速创建一个springboot web项目 <2> 5分钟集成好最新版本的开源swagger ui,并使用ui操作调用接口 <3> 5分钟集成好druid并使用druid自带监控工具监控sql请求 <4> 5分钟集成好mybatisplus并使用mybatisplus generator自…...
【设计模式-结构型】装饰器模式
一、什么是装饰器模式 装饰器模式(Decorator Pattern)是一种结构型设计模式,它的核心思想是在不改变原有对象结构的情况下,动态地给对象增加一些功能,从而达到扩展功能的目的。举个例子,今天在家妈妈给蒸馒…...
分布式数据存储基础与HDFS操作实践(副本)
以下为作者本人撰写的报告,步骤略有繁琐,不建议作为参考内容,可以适当浏览,进一步理解。 一、实验目的 1、理解分布式文件系统的基本概念和工作原理。 2、掌握Hadoop分布式文件系统(HDFS)的基本操作。 …...
Linux 进程前篇(冯诺依曼体系结构和操作系统)
目录 一.冯诺依曼体系结构 1.概念 2.硬件层面的数据流 3.总结加补充 二.操作系统 (Operating System) 1.概念 2.设计OS的目的 3.定位 4.操作系统的管理 5.计算机体系的层状结构 在我们认识进程之前,我们先了解什么是冯诺依曼体系结构 一.冯诺依曼体系结构…...
Springboot Redisson 分布式锁、缓存、消息队列、布隆过滤器
redisson-spring-boot-starter 是 Redisson 提供的 Spring Boot 集成包,旨在简化与 Redis 的交互,包括分布式锁、缓存、消息队列、布隆过滤器等功能的实现。 Maven 依赖 在 Spring Boot 项目中添加 redisson-spring-boot-starter 依赖: <…...
【C语言】_字符串拷贝函数strcpy
目录 1. 函数声明及功能 2. 使用示例 3. 注意事项 4. 模拟实现 4.1 第一版:基本功能判空const修饰 4.2 第二版:优化对于\0的单独拷贝 4.3 第三版:仿strcpy的char*返回值 1. 函数声明及功能 char * strcpy ( char * destination, cons…...
基于 Vue 的拖拽缩放卡片组件:实现思路、方法及使用指南
引言 在前端开发中,实现可交互的组件能够极大地提升用户体验。本文将介绍一个基于 Vue 封装的可缩放卡片组件,从实现思路、代码具体实现以及使用方法等方面进行详细阐述,帮助开发者更好地理解和运用这一组件。项目源码地址:https…...
nginx 实现 正向代理、反向代理 、SSL(证书配置)、负载均衡 、虚拟域名 ,使用其他中间件监控
我们可以详细地配置 Nginx 来实现正向代理、反向代理、SSL、负载均衡和虚拟域名。同时,我会介绍如何使用一些中间件来监控 Nginx 的状态和性能。 1. 安装 Nginx 如果你还没有安装 Nginx,可以通过以下命令进行安装(以 Ubuntu 为例࿰…...
Kafka客户端-“远程主机强迫关闭了一个现有的连接”故障排查及解决
Kafka客户端-“远程主机强迫关闭了一个现有的连接”故障排查及解决 1. 故障现象 Kafka客户端发送数据时,出现“远程主机强迫关闭了一个现有的连接”错误,导致数据发送失败。错误信息如下: 2. 故障排查 【1】. 查看服务网络状态 出现故障…...
Node.js - Express框架
1. 介绍 Express 是一个基于 Node.js 的 Web 应用程序框架,主要用于快速、简便地构建 Web 应用程序 和 API。它是目前最流行的 Node.js Web 框架之一,具有轻量级、灵活和功能丰富的特点。 核心概念包括路由,中间件,请求与响应&a…...
AWS Lambda
AWS Lambda 是 Amazon Web Services(AWS)提供的无服务器计算服务,它让开发者能够运行代码而不需要管理服务器或基础设施。AWS Lambda 会自动处理代码的执行、扩展和计费,开发者只需关注编写和部署代码,而无需担心底层硬…...
mysql 如何快速删除表数据
在数据库管理中, 经常会遇到需要删除大量数据的情况. 对于 MySQL 数据库而言, 如何高效快速地删除数据是一个值得深入探讨的问题. 本文将详细介绍几种在 MySQL 中快速删除数据的方法及相关注意事项. delete 语句 delete 语句可以删除符合条件的指定数据, 但是在删除大量数据…...
物联网网关Web服务器--lighttpd服务器部署与应用测试
以下是在国产ARM处理器E2000飞腾派开发板上部署 lighttpd 并进行 CGI 应用开发的步骤: 1、lighttpd简介 Lighttpd 是一款轻量级的开源 Web 服务器软件,具有以下特点和功能: 特点 轻量级:Lighttpd 在设计上注重轻量级和高效性&a…...
vmware虚拟机配置ubuntu 18.04(20.04)静态IP地址
VMware版本 :VMware Workstation 17 Pro ubuntu版本:ubuntu-18.04.4-desktop-amd64 主机环境 win11 1. 修改 VMware虚拟网络编辑器 打开vmware,点击顶部的“编辑"菜单,打开 ”虚拟化网络编辑器“ 。 选择更改设置&#…...
智能家居篇 一、Win10 VM虚拟机安装 Home Assistant 手把手教学
智能家居篇 一、Win10 VM虚拟机安装 Home Assistant 手把手教学 文章目录 [智能家居篇]( )一、Win10 VM虚拟机安装 Home Assistant 手把手教学 前言一.下载Vm版本的HomeAsistant安装包 二.打开Vmware选择新建虚拟机1.选择自定义高级2.选择16.x及以上3.选择稍后安装4.根据官网的…...
Flutter插件制作、本地/远程依赖及缓存机制深入剖析(原创-附源码)
Flutter插件在开发Flutter项目的过程中扮演着重要的角色,我们从 https://pub.dev 上下载添加到项目中的第三方库都是以包或者插件的形式引入到代码中的,这些第三方工具极大的提高了开发效率。 深入的了解插件的制作、发布、工作原理和缓存机…...
Python猜数小游戏
Python 实现的《猜数游戏》 介绍 本文将展示如何使用 Python 编写一个简单的《猜数游戏》。这个游戏将会生成一个1到10之间的随机数,用户有最多三次机会来猜测正确的数字。如果用户猜对了,游戏将结束并显示恭喜信息;如果没有猜对࿰…...
--- 用java实现一个计时器 ---
这里的计时器值得是当线程设定的时间过了之后,自动执行该线程的工作 设计 MyTimer 既然是要在指定的时间之后执行任务,那么传入的参数就应该有run方法(需要执行的任务),time(在多少时间之后执行ÿ…...
AI智能体架构设计:从成本黑洞到价值引擎的解耦之道
1. 从成本黑洞到价值引擎:为什么你的AI智能体架构正在吞噬预算又到了季度技术复盘会,财务那边递过来的云账单和工程人力成本,是不是又让你倒吸一口凉气?你看着报表上那个名为“AI智能体平台”的项目,它的资源消耗曲线几…...
Unity安卓打包实战指南:从环境配置到APK生成全链路排错
1. 这不是“入门教程”,而是一份写给真实开发现场的生存指南你打开Unity,新建一个3D项目,拖进一个Cube,点击Play——它动了。你松了口气,觉得“Unity好像也没那么难”。但当你把APK打包发给测试同事,对方回…...
从Gamma函数到泊松分布:一个概率论中的含参量积分实用案例解析
Gamma函数与泊松分布:概率论中的数学之美 在数据科学和机器学习的实践中,概率分布构成了建模的基石。当我们深入探究这些分布背后的数学原理时,Gamma函数以其优雅的性质和广泛的应用脱颖而出。它不仅连接了离散与连续概率世界,更在…...
数组专项(一):数组排序、去重、查找
大家好,欢迎来到《算法面试60讲(2026最新版全真题带解析)》第19篇!上一篇我们彻底吃透了字符串专项的核心难点——BF暴力匹配与KMP高效匹配算法,搞定了字符串模块面试最难的算法考点。从本节课开始,我们正式进入算法面试第一高频模块:数组专项。 在算法面试中,数组是出…...
GEO生成引擎优化:当AI成为信息分发的主角,品牌如何抢占对话窗口?
当用户不再"搜索-浏览",而是直接"AI提问-获取答案",传统SEO的逻辑正在被彻底改写。2026年,GEO(Generative Engine Optimization,生成式引擎优化)已经从概念走向规模化落地。本文从技术…...
Unity UI交互进阶:手把手教你打造一个支持单击、双击、长按的万能按钮组件
Unity UI交互进阶:手把手教你打造一个支持单击、双击、长按的万能按钮组件在游戏开发中,UI交互的流畅性和多样性直接影响玩家的游戏体验。想象一下,当你在开发一个RPG游戏的背包系统时,需要实现道具的单击查看详情、双击快速使用、…...
用Python复现Nature论文:仅需100次循环数据,提前预测锂电池寿命(附完整代码与数据集)
用Python实战预测锂电池寿命:从数据特征到模型部署全解析锂电池作为现代能源存储的核心组件,其寿命预测一直是工业界和学术界关注的焦点。传统方法往往需要等待电池出现明显容量衰减才能进行判断,而最新研究表明,通过分析早期循环…...
taotoken用量看板如何帮助团队精细化管理api调用成本
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 taotoken用量看板如何帮助团队精细化管理api调用成本 对于团队管理者而言,将大模型能力集成到产品开发或业务流程中&am…...
结肠“瑞士卷”制片法
在肠道病理研究中,如何完整保留小鼠结肠的全层结构、同时避免人为损伤,一直是实验操作的难点。本文分享一套改良版“瑞士卷”制片技术,无需剖开肠管、无需机械顶压,即可获得高质量的全结肠切片,特别适合炎症、隐窝异常…...
DeTikZify:基于AI的TikZ图形程序自动生成技术深度解析
DeTikZify:基于AI的TikZ图形程序自动生成技术深度解析 【免费下载链接】DeTikZify Synthesizing Graphics Programs for Scientific Figures and Sketches with TikZ. 项目地址: https://gitcode.com/gh_mirrors/de/DeTikZify DeTikZify是一款革命性的多模态…...
