两行代码轻轻松松搞定XML和对象之间的互转,非他莫属

本文主要是介绍两行代码轻轻松松搞定XML和对象之间的互转,非他莫属,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

推荐阅读:阿里P8架构师谈:工作1-5年的Java工程师,怎样提高核心竞争力

                  阿里架构师直言:“没有实战都是纸上谈兵”!Redis实战PDF分享

                  奋发图强半年多,终于四面阿里如愿拿到心仪offer定级P7

前言

在微信订阅号和支付宝生活号日常开发中,我们会涉及到对象和XML之间的相互转换。

轻松搞定XML和对象之间的互转,就它了!

比如我们可以利用StringBuilder去直接拼接来构造XML

    /*** 构造基础的响应消息* * @return*/public static String buildBaseAckMsg(String fromUserId) {StringBuilder sb = new StringBuilder();sb.append("<XML>");sb.append("<ToUserId><![CDATA[" + fromUserId + "]]></ToUserId>");sb.append("<AppId><![CDATA[" + AlipayServiceEnvConstants.APP_ID + "]]></AppId>");sb.append("<CreateTime>" + Calendar.getInstance().getTimeInMillis() + "</CreateTime>");sb.append("<MsgType><![CDATA[ack]]></MsgType>");sb.append("</XML>");return sb.toString();}

作为像我这么懒得程序员,肯定会去找大佬写好的轮子,这就是我和XStream相遇的契机。下面我们一起走进XStream

一.关于 XStream

Xstream 是一个简单的库,用于将对象序列化为 XML 然后再序列化回来。

二.简单入门

2.1 创建要序列化的类

这里有几个简单的类,XStream 可以将这些类的实例转换为 XML,然后再转换回来。

public class Person {private String firstname;private String lastname;private PhoneNumber phone;private PhoneNumber fax;// ... constructors and methods
}public class PhoneNumber {private int code;private String number;// ... constructors and methods
}

注意: 注意这些字段是私有的。Xstream 不关心字段的可见性。不需要getters or setters。此外,XStream 并不限制你拥有一个默认构造函数

2.2 初始化 XStream

引入依赖

<dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.10</version>
</dependency>

要使用 XStream,只需实例化 XStream 类:

XStream xstream = new XStream();

2.3.将序列化对象转为xml

让我们创建一个 Person 实例并填充它的字段:

        Person person = new Person("Joe", "milo");person.setPhone(new PhoneNumber(123,"1234-456"));person.setFax(new PhoneNumber(123,"999-456"));

现在,要将其转换为XML,只需要简单的调用XStream的toXML()方法

String xml = xstream.toXML(person);

 

轻松搞定XML和对象之间的互转,就它了!

 

现在,为了使 XStream 输出的 XML 更简洁,可以为 XML 元素名的自定义类名创建别名。这是使用 XStream 所需的惟一映射类型,当然这是可选的。

xstream.alias("person",Person.class);

我们会发现XML变得更简洁

轻松搞定XML和对象之间的互转,就它了!

2.4.将XML反序列化对象

首先,我们重写Person对象的toString()

    @Overridepublic String toString() {return "Person{" +"firstname='" + firstname + ''' +", lastname='" + lastname + ''' +", phone=" + phone +", fax=" + fax +'}';}

要重构一个对象,我们只需调用fromXML()方法

        XStream xstream = new XStream();xstream.alias("person",Person.class);//xml字符串String xmldemo = "<?xml version="1.0" ?><person><firstname>Joe</firstname><lastname>milo</lastname><phone><code>123</code><number>1234-456</number></phone><fax><code>123</code><number>999-456</number></fax></person>";Person o = (Person)xstream.fromXML(xmldemo);System.out.println(o.toString());

 

轻松搞定XML和对象之间的互转,就它了!

 

关于更多关于Xstream的操作,大家可以阅读:

https://www.cnblogs.com/jpfss/p/9836465.html

三.高级入门

在高级入门中,我们以支付宝生活号开发为例,采用Xstream的注解开发来完成事件订阅过程中的xml报文相关的操作

3.1 项目搭建

首先我们搭建项目springboot-xstream,当然你可以在

https://gitee.com/milogenius/milogenius-springboot

找到源代码,案例位于springboot-xstream模块下面。由于案例代码太多,强烈建议大家下载源代码案例自己跑一跑。

轻松搞定XML和对象之间的互转,就它了!

 

3.2 相关类解释

轻松搞定XML和对象之间的互转,就它了!

 

3.3 和XStream相关的类

1.AlipayXmlMessage
package com.milo.xstream.xml;import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;import java.io.InputStream;
import java.io.Serializable;
import java.util.Map;/*** 支付宝生活号推送过来的xml消息* @author milogenius* @date 2020/4/4 15:29**/
@Data
@Slf4j
@XStreamAlias("XML")
public class AlipayXmlMessage implements Serializable {private static final long serialVersionUID = -3586245291677274914L;/*** 使用dom4j解析的存放所有xml属性和值的map.*/private Map<String, Object> allFieldsMap;///// 以下都是支付宝生活号推送过来的消息的xml的element所对应的属性////**AppId*///AppId--->xml中的字段//appId --->pojo中的字段@XStreamAlias("AppId")@XStreamConverter(value = XStreamCDataConverter.class)private String appId;/**用户userid,用户唯一标识*/@XStreamAlias("FromAlipayUserId")@XStreamConverter(value = XStreamCDataConverter.class)private String fromAlipayUserId;/**消息创建时间*/@XStreamAlias("CreateTime")private Long createTime;/**消息类型*/@XStreamAlias("MsgType")@XStreamConverter(value = XStreamCDataConverter.class)private String msgType;/**事件类型*/@XStreamAlias("EventType")@XStreamConverter(value = XStreamCDataConverter.class)private String eventType;/**用户从特定场景关注,带的自定义参数值*/@XStreamAlias("ActionParam")@XStreamConverter(value = XStreamCDataConverter.class)private String actionParam;/**支付宝用户信息*/@XStreamAlias("UserInfo")@XStreamConverter(value = XStreamCDataConverter.class)private String userInfo;/**消息id 用于消息去重*/@XStreamAlias("MsgId")private String msgId;public static AlipayXmlMessage fromXml(String xml) {//修改支付宝生活号变态的消息内容格式,方便解析xml = xml.replace("<?xml version=\"1.0\" encoding=\"gbk\"?>", "");final AlipayXmlMessage xmlMessage = XStreamTransformer.fromXml(AlipayXmlMessage.class, xml);xmlMessage.setAllFieldsMap(XmlUtils.xml2Map(xml));return xmlMessage;}public static AlipayXmlMessage fromXml(InputStream is) {return XStreamTransformer.fromXml(AlipayXmlMessage.class, is);}}

2.AlipayXmlOutMessage

package com.milo.xstream.outxml;import com.milo.xstream.builder.AckBuilder;
import com.milo.xstream.xml.XStreamCDataConverter;
import com.milo.xstream.xml.XStreamTransformer;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;import java.io.Serializable;/*** 响应XML* @author milogenius* @date 2020/4/4 11:57**/
@XStreamAlias("xml")
@Data
public abstract class AlipayXmlOutMessage implements Serializable {private static final long serialVersionUID = -381382011286216263L;/**接受者userid*/@XStreamAlias("ToUserId")@XStreamConverter(value = XStreamCDataConverter.class)protected String toUserId;/**支付宝生活号appid*/@XStreamAlias("AppId")@XStreamConverter(value = XStreamCDataConverter.class)protected String appId;/**创建时间*/@XStreamAlias("CreateTime")protected Long createTime;/**消息类型*/@XStreamAlias("MsgType")@XStreamConverter(value = XStreamCDataConverter.class)protected String msgType;@XStreamAlias("response")protected Response response;@XStreamAlias("sign")protected String sign;@XStreamAlias("sign_type")protected String signType;/*** 获得ack builder* @return*/public static AckBuilder ACK() {return new AckBuilder();}@SuppressWarnings("unchecked")public String toXml() {StringBuilder builder = new StringBuilder();String xml = XStreamTransformer.toXml((Class<AlipayXmlOutMessage>) this.getClass(), this);builder.append("<?xml version="1.0" encoding="gbk"?>n");builder.append(xml);return builder.toString();}}

3.XStreamCDataConverter

package com.milo.xstream.xml;import com.thoughtworks.xstream.converters.basic.StringConverter;
/*** 自定义转换器* @author milogenius* @date 2020/4/4 10:56**/
public class XStreamCDataConverter extends StringConverter {@Overridepublic String toString(Object obj) {return "<![CDATA[" + super.toString(obj) + "]]>";}}

相关注解说明

@XStreamAlias用于定义XStream类或字段别名的注释

@XStreamConverter用于声明转换器的注释

3.4 测试

XmlDemoTest

package com.milo.xstream;import com.milo.xstream.outxml.AlipayXmlOutMessage;
import com.milo.xstream.xml.AlipayXmlMessage;/*** @author milogenius* @date 2020-04-04 11:49*/
public class XmlDemoTest {public static void main(String[] args) {//xml --->pojoString bizContent = "<XML>n" +"    <AppId><![CDATA[2014070100171523]]></AppId>n" +"    <FromUserId><![CDATA[20882837462837462837462837461234]]></FromUserId>n" +"    <FromAlipayUserId><![CDATA[2088283746283746]]></FromAlipayUserId>n" +"    <CreateTime><![CDATA[1405943673657]]></CreateTime>n" +"    <MsgType><![CDATA[event]]></MsgType>n" +"    <EventType><![CDATA[follow]]></EventType>n" +"    <ActionParam><![CDATA[{"scene":{"sceneId": "1234"}}]]></ActionParam>n" +"    <AgreementId><![CDATA[]]></AgreementId>n" +"    <AccountNo><![CDATA[]]></AccountNo>n" +"    <UserInfo><![CDATA[{"logon_id":"135****1009","user_name":"*iuxu527"}]]></UserInfo>n" +"</XML>";AlipayXmlMessage alipayXmlMessage = AlipayXmlMessage.fromXml(bizContent);// System.out.println(alipayXmlMessage);//pojo --->xmlAlipayXmlOutMessage mpXmlOutMessage = AlipayXmlOutMessage.ACK().toUserId("123456").appId("99999999").build();String xml = mpXmlOutMessage.toXml();System.out.println(xml);}
}

3.5测试结果

3.5.1 xml ---->pojo

轻松搞定XML和对象之间的互转,就它了!

 

3.5.2 pojo --->xml

轻松搞定XML和对象之间的互转,就它了!

 

四.总结

通过上面的一些小案例,我们学习Xstream的基本用法和注解用法,文章到此为止,谢谢大家阅读;

这篇关于两行代码轻轻松松搞定XML和对象之间的互转,非他莫属的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/286222

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

Java文件与Base64之间的转化方式

《Java文件与Base64之间的转化方式》这篇文章介绍了如何使用Java将文件(如图片、视频)转换为Base64编码,以及如何将Base64编码转换回文件,通过提供具体的工具类实现,作者希望帮助读者... 目录Java文件与Base64之间的转化1、文件转Base64工具类2、Base64转文件工具类3、

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav