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方法,这样就会正常序列化。

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

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

相关文章

【时时三省】(C语言基础)柔性数组的使用

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 示例&#xff1a; 柔性数组是一次性开辟的一块空间&#xff0c;实际上后面arr的空间是通过预设的方式&#xff0c;给它增加了一块空间 用柔性数组得好处 第一个好处是&#xff1a;方便内存…

RAG 切块Chunk技术总结与自定义分块实现思路

TrustRAG项目地址&#x1f31f;&#xff1a;https://github.com/gomate-community/TrustRAG 可配置的模块化RAG框架 切块简介 在RAG&#xff08;Retrieval-Augmented Generation&#xff09;任务中&#xff0c;Chunk切分是一个关键步骤&#xff0c;尤其是在处理结构复杂的PDF文…

【MySQL】数据库约束和多表查询

目录 1.前言 2.数据库约束 2.1约束类型 2.2?NULL约束 2.3 NUIQUE&#xff1a;唯一约束 2.4?DEFAULT&#xff1a;默认值约束 2.5?PRIMARY KEY&#xff1a;主键约束 2.6 FOREIGN KEY&#xff1a;外键约束 1.7?CHECK约束 3.表的设计? 3.1一对一 3.2一对多 3.3多…

解锁C#语法的无限可能:从基础到进阶的编程之旅

目录 一、C# 基础语法 1.1 数据类型 1.2 变量与常量 1.3 运算符 1.4 控制流语句 二、C# 面向对象编程语法 2.1 类与对象 2.2 封装 2.3 继承 2.4 多态 虚方法 抽象类 接口 三、C# 高级语法 3.1 特性&#xff08;Attribute&#xff09; 预定义特性 自定义特性 3…

【2024年华为OD机试】 (C卷,100分)- 小明找位置(Java JS PythonC/C++)

一、问题描述 题目描述 小朋友出操&#xff0c;按学号从小到大排成一列&#xff1b; 小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n)&#xff1b;学号为整数类型&#xff0c;队列规模 ≤ 10000&#xff1…

vue2配置跨域后请求的是本机

这个我来说明一下&#xff0c;因为我们公司的后端设置解决了跨域问题&#xff0c;所以我有很久没有看相关的内容了&#xff0c;然后昨天请求了需要跨域的接口&#xff0c;请求半天一直不对&#xff0c;浏览器显示的是本机地址&#xff0c;我以为是自己配置错了&#xff0c;后面…

【Uniapp-Vue3】@import导入css样式及scss变量用法与static目录

一、import导入css样式 在项目文件中创建一个common文件夹&#xff0c;下面创建一个css文件夹&#xff0c;里面放上style.css文件&#xff0c;编写的是公共样式&#xff0c;我们现在要在App.vue中引入该样式。 在App.vue中引入该样式&#xff0c;这样就会使样式全局生效&#…

大模型WebUI:Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(6)

大模型WebUI&#xff1a;Gradio全解11——Chatbot&#xff1a;融合大模型的多模态聊天机器人&#xff08;6&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.6 为LLM Agent构建UI11.5.1 使用代理构建1. 使用transformers.agents的实际示例2. 使…

【React】插槽渲染机制

目录 通过 children 属性结合条件渲染通过 children 和 slot 属性实现具名插槽通过 props 实现具名插槽 在 React 中&#xff0c;并没有直接类似于 Vue 中的“插槽”机制&#xff08;slot&#xff09;。但是&#xff0c;React 可以通过 props和 children 来实现类似插槽的功能…

LoadBalancer负载均衡服务调用

LoadBalancer LoadBalancer&#xff08;负载均衡器&#xff09;是Spring Cloud中的一个关键组件&#xff0c;用于在微服务架构中实现服务请求的负载均衡。它的主要作用是将客户端的请求分发到多个服务实例上&#xff0c;以提高系统的可用性、性能和容错能力。通过LoadBalancer&…

Linux操作命令之云计算基础命令

一、图形化界面/文本模式 ctrlaltF2-6 图形切换到文本 ctrlalt 鼠标跳出虚拟机 ctrlaltF1 文本切换到图形 shift ctrl "" 扩大 ctrl "-" 缩小 shift ctrl "n" 新终端 shift ctrl "t" 新标签 alt 1,…

简历_使用优化的Redis自增ID策略生成分布式环境下全局唯一ID,用于用户上传数据的命名以及多种ID的生成

系列博客目录 文章目录 系列博客目录WhyRedis自增ID策略 Why 我们需要设置全局唯一ID。原因&#xff1a;当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增ID就存在一些问题。 问题&#xff1a;id的规律性太明显、…

企业邮箱iRedMail搭建

用自己的域名作为邮箱的后缀&#xff0c;好看、有面子&#xff01;只要域名不过期&#xff0c;那么&#xff0c;你的邮箱就永远存在&#xff01; 邮件系统很多&#xff0c;宝塔自带的邮局更是简单&#xff0c;但是若想邮箱可靠&#xff08;丢邮件、发送邮件进入对方垃圾箱等&a…

在 Fluent 网格划分中使用薄网格特征

薄体模型的网格划分策略 薄体网格划分对于有效模拟薄壁结构或厚度明显小于其他尺寸的几何形状非常有利。当使用此类几何结构时&#xff0c;传统的体积网格划分技术可能会导致单元数量增加&#xff0c;因为它们试图捕获具有许多不必要单元的薄尺寸。薄体网格划分通过专门沿薄方…

Windows重装后NI板卡LabVIEW恢复正常

在重新安装Windows系统后&#xff0c;NI&#xff08;National Instruments&#xff09;板卡能够恢复正常工作&#xff0c;通常是由于操作系统的重新配置解决了之前存在的硬件驱动、兼容性或配置问题。操作系统重装后&#xff0c;系统重新加载驱动程序、清理了潜在的冲突或损坏的…

Html5 video标签学习

<video> 标签的属性 autoplay布尔属性声明该属性后&#xff0c;视频会尽快自动开始播放&#xff0c;不会停下来等待数据全部加载完成。controls布尔属性如果存在该属性&#xff0c;浏览器会在视频底部提供一个控制面板&#xff0c;允许用户控制视频的播放。controlslist…

OpenAI推出首个AI Agent!日常事项自动化处理!

2025 年1月15日&#xff0c;OpenAI 正式宣布推出一项名为Tasks的测试版功能 。 该功能可以根据你的需求内容和时间实现自动化处理。比方说&#xff0c;你可以设置每天早晨 7 点获取天气预报&#xff0c;或定时提醒遛狗等日常事项。 看到这里&#xff0c;有没有一种熟悉的感觉&a…

【Linux】Socket编程-TCP构建自己的C++服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; Socket 编程 TCP &#x1f98b; TCP socket API 详解&#x1f98b; 多线程远程命令执行&#x1f98b; 网络版计算器&#xff08;应用层自定义协议与序列化…

web开发工具之:三、JWT的理论知识,java的支持,封装的工具类可以直接使用

文章目录 前言一、JWT的理论知识1. 什么是 JWT&#xff08;JSON Web Token&#xff09;&#xff1f;2. **JWT 的组成**3. **JWT 的特点**4. **JWT 的使用场景**5. **JWT 的生命周期**6. **JWT 的优点**7. **JWT 的注意事项**5. **JWT 示例**总结 二、java的springboot支持1. po…

Jira中bug的流转流程

Jira中bug的状态 1. 处理Bug的流程2. bug状态流转详述bug的状态通常包括 1. 处理Bug的流程 2. bug状态流转详述 bug的状态通常包括 未解决 1. 测试人员创建一个bug&#xff0c;填写bug的详细信息&#xff0c;如概要、bug级别、复现步骤、现状、预期结果等 2. 定位bug&#x…