# varFormatter 数据格式化 技术 *开源技术栏* 将一个 对象/变量 进行按照 JSON XML HTML 等格式进行转换,并获取到结果! ## 目录 [TOC]  ## 介绍 通过此库,您可以实现将一个任意类型的对象进行按照 JSON XML HTML 等格式进行转换,并获取到结果字符串,是非常方便的数据对象格式化工具库,其具有强大的性能和类反射的缓存机制,能够不进行过多的解析和转换! ### 获取方式 您可以直接通过 maven 获取到此库的依赖,下面是一个依赖的实例。 ```xml <dependencies> <!-- 引入库的依赖 --> <dependency> <groupId>io.github.BeardedManZhao</groupId> <artifactId>varFormatter</artifactId> <version>1.0.1</version> </dependency> <!-- 引入库所需要的工具类 --> <dependency> <groupId>io.github.BeardedManZhao</groupId> <artifactId>zhao-utils</artifactId> <version>1.0.20240121</version> </dependency> </dependencies> ``` ## 使用示例 本小节将演示 varFormatter 的使用案例!您根据案例可以快速了解其使用方法! ### 格式化组件的基本使用 在下面我们将使用各种 varFormatter 进行一些对象的格式化操作! #### 获取到格式化组件 在这里我们提供了一个实例,在实例中,通过 VarFormatter 获取到了 json 格式化组件,并演示了 `getFormatter(boolean)` 函数中的形参的作用! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; public class Test { public static void main(String[] args) { // 使用单例模式 获取到 json 格式化组件 final Formatter formatter0 = VarFormatter.JSON.getFormatter(true); // 使用单例模式 再次获取到 json 的格式化组件 final Formatter formatter1 = VarFormatter.JSON.getFormatter(true); // 使用多例模式 获取到 json 格式化组件 final Formatter formatter2 = VarFormatter.JSON.getFormatter(false); // 判断三个组件的内存地址是否相同 // 结论 单例获取到的都是同一个内存地址的组件 System.out.println(formatter0 == formatter1); System.out.println(formatter0 == formatter2); System.out.println(formatter1 == formatter2); } } ``` #### 格式化一个任意类型的对象 在此库中,我们提供了一个 `format(Object)` 函数,可以将任意类型的对象进行格式化!其基于反射+缓存机制,相同对象的结构只会被解析一次! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 json 格式化组件 final Formatter formatter0 = VarFormatter.JSON.getFormatter(true); // 实例化两个 TestObj 对象 TestObj testObj1 = new TestObj(); TestObj testObj2 = new TestObj(); // 修改第二个对象中的 age 为 2048 testObj2.age = 2048; // 将两个对象进行格式化操作 获取到对象的 json 结构 System.out.println(formatter0.format(testObj1)); System.out.println(formatter0.format(testObj2)); } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); } public static class TestObj2 { String name = "zhao123"; ArrayList<Integer> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` 下面就是格式化的两个 json 的结果 ```json { "data": { "k1": "123123", "k": 123123 }, "name": "zhao", "age": 1024, "testObj2": { "name": "zhao123", "arrayList": [ 1, 2, 3, 4 ] } } { "data": { "k1": "123123", "k": 123123 }, "name": "zhao", "age": 2048, "testObj2": { "name": "zhao123", "arrayList": [ 1, 2, 3, 4 ] } } ``` #### 格式化一个Map对象 当我们的对象是一个 Map 对象时,我们可以通过 `format(Map)` 函数进行格式化,此方法具有更快的速度,能够实现更加稳定和快速的功能。 ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 创建一个 Map 对象 final HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("age", 21); hashMap.put("name", "ly"); // 再创建一个 Map 对象 final HashMap<String, Object> hashMap1 = new HashMap<>(); hashMap1.put("age", 22); hashMap1.put("name", "ty"); // Map 中再嵌套一个子Map hashMap.put("friend", hashMap1); // 使用单例模式 获取到 json 格式化组件 final Formatter formatter0 = VarFormatter.JSON.getFormatter(true); // 直接根据 Map 对象进行格式化 System.out.println(formatter0.format(hashMap)); } } ``` 下面就是格式化的结果 ```json { "name": "ly", "friend": { "name": "ty", "age": 22 }, "age": 21 } ``` #### 格式化一个 DataObj 对象 此对象是一个内置的数据节点类,可以直接被解析成为一种 Map 的方式来进行格式化,不需要进行任意的结构解析和反射操作,因此性能较号。 ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 获取到 json 格式化组件 final Formatter formatter = VarFormatter.JSON.getFormatter(true); // 将 对象转为 json 格式 System.out.println(formatter.format(new TestObj())); // 获取到 xml 格式化组件 final Formatter formatter1 = VarFormatter.XML.getFormatter(true); // 将 对象转为 xml 格式 System.out.println(formatter1.format(new TestObj())); // 获取到 html 格式化组件 final Formatter formatter2 = VarFormatter.HTML.getFormatter(true); // 将 对象转为 html 格式 System.out.println(formatter2.format(new HtmlObj())); } static class HtmlObj { String h1 = "大标题"; String h2 = "小标题"; List<li> ul = new ArrayList<>(); { ul.add(new li()); ul.add(new li()); ul.add(new li()); } static class li { String li = "行数据"; } } static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); } public static class TestObj2 { String name = "zhao123"; ArrayList<Integer> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` #### 格式化一个 XmlNodeObj 对象 `XmlNodeObj` 是 `DataObj` 的子类,其具有`DataObj` 的所有特点,但是其还具有属性的功能,它能够接收一些属性,格式化组件会按照这个属性自动构造数据。 ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import top.lingyuzhao.varFormatter.utils.XmlNodeObj; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 HTML 格式化组件 final Formatter formatter0 = VarFormatter.HTML.getFormatter(true); // 构建一个 body 和 html 标签 final XmlNodeObj body = new XmlNodeObj("body"); final XmlNodeObj xmlNodeObj = new XmlNodeObj("html", body); // 设置 html 标签的 lang 属性 xmlNodeObj.setAttr("lang", "zh"); // 设置body标签内部的标签 body.put("p", "这里是一些段落文本"); // 在body标签内部添加一个div标签 final XmlNodeObj div = new XmlNodeObj("div"); // 设置 div 标签的属性 这里是设置的字体颜色 div.setAttr("style", "color:#0f0"); // 设置 div 标签内部的文本 div.put("div", "这里是一些 div 中的段落文本"); // 把 div 标签提供给 body body.put(div); // 直接打印出 HTML 格式的文本 System.out.println(formatter0.format(xmlNodeObj)); } } ``` 下面是格式化之后的结果 ```html <html lang="zh"> <body><p>这里是一些段落文本</p> <div style="color:#0f0"> <div>这里是一些 div 中的段落文本</div> </div> </body> </html> ``` ### 各类格式化组件的使用 处理 json 类型的格式化组件,还有其它的型号,xml 格式化组件,html 格式化组件以及其它组件,都具有相同的使用方法,下面就是使用方法的演示实例。 #### xml 格式化组件演示实例 处理 xml 类型的格式化组件,它能够将任意的对象使用标签的方式转换成为一个 xml 格式的文本,xml 类型是具有根节点的,如果您格式化的是一个Map类型的对象,是支持指定根节点名字的,要指定根节点可以在 `format` 函数中指定 name 参数! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 XML 格式化组件 final Formatter formatter0 = VarFormatter.XML.getFormatter(true); // 将对象进行格式化操作 获取到对象的 xml 结构 System.out.println(formatter0.format(new TestObj())); } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); } public static class TestObj2 { String name = "zhao123"; ArrayList<Integer> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` 下面是处理之后的 xml 字符串 ```xml <TestObj> <data> <k1>123123</k1> <k>123123</k> </data> <name>zhao</name> <age>1024</age> <testObj2> <name>zhao123</name> <arrayList> <arrayList>1</arrayList> <arrayList>2</arrayList> <arrayList>3</arrayList> <arrayList>4</arrayList> </arrayList> </testObj2> </TestObj> ``` #### html 格式化组件演示实例 此组件是 HTML 格式化组件,是 xml 格式化组件的子类,它可以在实现 xml/html 格式转换的前提下,还保证其中字段的顺序,这对于html来说是很重要的,如果html 中的标签顺序不一致,则页面会错乱! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 HTML 格式化组件 final Formatter formatter0 = VarFormatter.HTML.getFormatter(true); // 将对象进行格式化操作 获取到对象的 HTML 结构 System.out.println(formatter0.format(new TestObj())); } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); } public static class TestObj2 { String name = "zhao123"; ArrayList<Integer> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` 下面是处理之后的字符串 ```xml <TestObj> <name>zhao</name> <age>1024</age> <data> <k1>123123</k1> <k>123123</k> </data> <testObj2> <name>zhao123</name> <arrayList> <arrayList>1</arrayList> <arrayList>2</arrayList> <arrayList>3</arrayList> <arrayList>4</arrayList> </arrayList> </testObj2> </TestObj> ``` #### Mermaid 格式化组件演示实例 Mermaid 是一种图结构的格式化组件,它能够将任意的类结构转换为 Mermaid 格式的文本,Mermaid 格式是具有图结构的,您可以将一个对象直接按照 Mermaid 类结构进行转换,这经常能够适用于观察类结构的场景,接下来就是有关的代码示例! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 MERMAID 格式化组件 final Formatter formatter0 = VarFormatter.MERMAID.getFormatter(true); // 将对象进行格式化操作 获取到对象的 MERMAID 结构图的代码 并打印出来 System.out.println("graph LR"); System.out.println(formatter0.format(new TestObj())); } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); } public static class TestObj2 { String name = "zhao123"; ArrayList<Object> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); // 这里使用了一个 Date 类 增大 类的复杂度 arrayList.add(new Date()); } } } } ``` 下面是运行结果,可以直接做为 Mermaid 图展示! ```mermaid graph LR TestObj==Map>Map==>TestObj.data TestObj.data==Map>String/Number==>TestObj.data.k1 TestObj.data.k1--Map>value-->TestObj.data.k1v{"123123"} TestObj.data==Map>String/Number==>TestObj.data.k TestObj.data.k--Map>value-->TestObj.data.kv{"123123"} TestObj==Map>String/Number==>TestObj.name TestObj.name--Map>value-->TestObj.namev{"zhao"} TestObj==Map>String/Number==>TestObj.age TestObj.age--Map>value-->TestObj.agev{"1024"} TestObj==Map>Object==>TestObj.testObj2 TestObj.testObj2==Map>String/Number==>TestObj.testObj2.name TestObj.testObj2.name--Map>value-->TestObj.testObj2.namev{"zhao123"} TestObj.testObj2==Map>Collection==>TestObj.testObj2.arrayList TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.1 TestObj.testObj2.arrayList.1--Collection>value-->TestObj.testObj2.arrayList.1v(("1")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.2 TestObj.testObj2.arrayList.2--Collection>value-->TestObj.testObj2.arrayList.2v(("2")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.3 TestObj.testObj2.arrayList.3--Collection>value-->TestObj.testObj2.arrayList.3v(("3")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.4 TestObj.testObj2.arrayList.4--Collection>value-->TestObj.testObj2.arrayList.4v(("4")) TestObj.testObj2.arrayList==Collection>Object==>TestObj.testObj2.arrayList.5 TestObj.testObj2.arrayList.5==Map>String/Number==>TestObj.testObj2.arrayList.5.serialVersionUID TestObj.testObj2.arrayList.5.serialVersionUID--Map>value-->TestObj.testObj2.arrayList.5.serialVersionUIDv{"7523967970034938905"} TestObj.testObj2.arrayList.5==Map>Object==>TestObj.testObj2.arrayList.5.ttb TestObj.testObj2.arrayList.5==Map>Object==>TestObj.testObj2.arrayList.5.wtb TestObj.testObj2.arrayList.5==Map>String/Number==>TestObj.testObj2.arrayList.5.fastTime TestObj.testObj2.arrayList.5.fastTime--Map>value-->TestObj.testObj2.arrayList.5.fastTimev{"1709990413635"} TestObj.testObj2.arrayList.5==Map>Object==>TestObj.testObj2.arrayList.5.gcal TestObj.testObj2.arrayList.5==Map>String/Number==>TestObj.testObj2.arrayList.5.defaultCenturyStart TestObj.testObj2.arrayList.5.defaultCenturyStart--Map>value-->TestObj.testObj2.arrayList.5.defaultCenturyStartv{"0"} ``` ### 数据输出方法的示例 库中针对一个实例进行格式转换之后会将结果返回给用户,而返回的结果可以是字符串或者数据流,下面就是关于数据流输出的示例! #### 字符串输出 您可以调用 `Formatter.format` 方法进行字符串输出!这样的操作从库的首个版本发布之后就被支持了,您可以很方便地使用它,在上面的诸多示例中使用的也是字符串输出,下面是一个示例! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.util.ArrayList; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) { // 使用单例模式 获取到 MERMAID 格式化组件 final Formatter formatter0 = VarFormatter.MERMAID.getFormatter(true); // 将对象进行格式化操作 获取到对象的 MERMAID 结构图的代码 System.out.println("graph LR"); System.out.println(formatter0.format(new TestObj())); } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); data.put("k2", new HashMap<>()); } public static class TestObj2 { String name = "zhao123"; ArrayList<Object> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` 下面就是运行结果 ```mermaid graph LR map==Map>Map==>map.data map.data==Map>String/Number==>map.data.k1 map.data.k1--Map>value-->map.data.k1v{"123123"} map.data==Map>Map==>map.data.k2 map.data==Map>String/Number==>map.data.k map.data.k--Map>value-->map.data.kv{"123123"} map==Map>String/Number==>map.name map.name--Map>value-->map.namev{"zhao"} map==Map>String/Number==>map.age map.age--Map>value-->map.agev{"1024"} map==Map>Object==>map.testObj2 map.testObj2==Map>String/Number==>map.testObj2.name map.testObj2.name--Map>value-->map.testObj2.namev{"zhao123"} map.testObj2==Map>Collection==>map.testObj2.arrayList map.testObj2.arrayList==Collection>String/Number==>map.testObj2.arrayList.1 map.testObj2.arrayList.1--Collection>value-->map.testObj2.arrayList.1v(("1")) map.testObj2.arrayList==Collection>String/Number==>map.testObj2.arrayList.2 map.testObj2.arrayList.2--Collection>value-->map.testObj2.arrayList.2v(("2")) map.testObj2.arrayList==Collection>String/Number==>map.testObj2.arrayList.3 map.testObj2.arrayList.3--Collection>value-->map.testObj2.arrayList.3v(("3")) map.testObj2.arrayList==Collection>String/Number==>map.testObj2.arrayList.4 map.testObj2.arrayList.4--Collection>value-->map.testObj2.arrayList.4v(("4")) ``` #### 数据流输出 在 1.0.2 版本中,我们添加了数据流输出方法,您可以调用 `Formatter.formatToStream` 方法进行数据流输出!下面是一个示例! ```java import top.lingyuzhao.varFormatter.core.Formatter; import top.lingyuzhao.varFormatter.core.VarFormatter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; /** * 测试类 * * @author zhao */ public class Test { public static void main(String[] args) throws IOException { // 获取到一个字符串数据输出流 try ( final StringWriter stringWriter = new StringWriter(); final PrintWriter bufferedWriter = new PrintWriter(stringWriter) ) { // 使用单例模式 获取到 MERMAID 格式化组件 final Formatter formatter0 = VarFormatter.MERMAID.getFormatter(true); // 将对象进行格式化操作 获取到对象的 MERMAID 结构图的代码 并写到 bufferedWriter 中 // 只需要调用 formatToStream 函数即可 formatter0.formatToStream(new TestObj(), bufferedWriter); // 查看 stringWriter 中是否有数据 // 由于是往 bufferedWriter 里面写的数据 bufferedWriter 中的数据流是 stringWriter // 因此相当于是往 stringWriter 中写入了数据 System.out.println("graph LR"); System.out.println(stringWriter); } } // 准备了一个复杂的类 static class TestObj { String name = "zhao"; int age = 1024; HashMap<String, Object> data = new HashMap<>(); TestObj2 testObj2 = new TestObj2(); { data.put("k", 123123); data.put("k1", "123123"); data.put("k2", new HashMap<>()); } public static class TestObj2 { String name = "zhao123"; ArrayList<Object> arrayList = new ArrayList<>(); { arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); } } } } ``` 下面就是运行结果! ```mermaid graph LR TestObj==Map>Map==>TestObj.data TestObj.data==Map>String/Number==>TestObj.data.k1 TestObj.data.k1--Map>value-->TestObj.data.k1v{"123123"} TestObj.data==Map>Map==>TestObj.data.k2 TestObj.data==Map>String/Number==>TestObj.data.k TestObj.data.k--Map>value-->TestObj.data.kv{"123123"} TestObj==Map>String/Number==>TestObj.name TestObj.name--Map>value-->TestObj.namev{"zhao"} TestObj==Map>String/Number==>TestObj.age TestObj.age--Map>value-->TestObj.agev{"1024"} TestObj==Map>Object==>TestObj.testObj2 TestObj.testObj2==Map>String/Number==>TestObj.testObj2.name TestObj.testObj2.name--Map>value-->TestObj.testObj2.namev{"zhao123"} TestObj.testObj2==Map>Collection==>TestObj.testObj2.arrayList TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.1 TestObj.testObj2.arrayList.1--Collection>value-->TestObj.testObj2.arrayList.1v(("1")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.2 TestObj.testObj2.arrayList.2--Collection>value-->TestObj.testObj2.arrayList.2v(("2")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.3 TestObj.testObj2.arrayList.3--Collection>value-->TestObj.testObj2.arrayList.3v(("3")) TestObj.testObj2.arrayList==Collection>String/Number==>TestObj.testObj2.arrayList.4 TestObj.testObj2.arrayList.4--Collection>value-->TestObj.testObj2.arrayList.4v(("4")) ``` ## 更新记录 ### 2024-03-xx _开发 1.0.2 版本!【此版本还未发布!】_ - 增加了 yaml 格式化组件! - 增加了数据流的格式转换结果输出方法! ### 2024-03-09 _发布 1.0.1 版本!_ - 针对具有 `null` 值的类的转换工作也可以顺利完成了! - 增加了 Mermaid 格式化组件!您可以在 《Mermaid 格式化组件演示实例》 小节中查看到相关的调用! ### 2024-03-01 _初次发布 1.0.0 版本!_ - 支持 json xml html 格式化! - 提供了 DataObj 和 XmlNodeObj 类,能够用于进行转换。 - 提供了针对类结构的解析模块,能够将任意的类结构转换为 json xml html 格式! ------ ***操作记录*** 作者:[root](https://www.lingyuzhao.top//index.html?search=1 "root") 操作时间:2024-03-10 21:38:42 星期日 事件描述备注:保存/发布 中国 天津 [](如果不需要此记录可以手动删除,每次保存都会自动的追加记录)