【Java对象转换】003- Java 对象与 Yaml 互转

【Java对象转换】003- Java 对象与 Yaml 互转

一、Java 对象与 Yaml 概述

1、Java 对象

  • Java对象是数据和处理可用数据的过程的组合;
  • 对象既有状态又有行为 。 在Java中,使用关键字“ new”创建对象;
  • 对象是从称为类的模板创建的;
  • 对象是类的实例。

2、Yaml

可参考本人其他文章:《【Spring Boot】003-yaml语法》 https://blog.csdn.net/qq_29689343/article/details/108545693 二、yaml语法

二、Java 对象与 Yaml 互转

1、使用 jackson dataformat yaml

jackson dataformat yaml,是用来读取yaml文件,并且反序列化到对象中的一个模块。

此处使用 2.13.2 会报错:java.lang.NoSuchMethodError: ‘com.fasterxml.jackson.core.io.ContentReference com.fasterxml.jackson.dataformat.yaml.YAMLFactory._createContentReference(java.lang.Object)’

第一步:在 pom.xml下引入依赖

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.12.4</version>
</dependency>

第二步:写个工具类

package com.zibo.api.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;

import java.io.IOException;
import java.io.StringWriter;

/**
 * 对象与yaml字符串互转工具:测试完成,时间:2021年08月06日 14时08分18秒
 */
public class YamlUtil {
    /**
     * 将yaml字符串转成类对象
     * @param yamlStr 字符串
     * @param clazz 目标类
     * @param <T> 泛型
     * @return 目标类
     */
    public static <T> T toObject(String yamlStr, Class<T> clazz){
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        mapper.findAndRegisterModules();
        try {
            return mapper.readValue(yamlStr, clazz);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将类对象转yaml字符串
     * @param object 对象
     * @return yaml字符串
     */
    public static String toYaml(Object object){
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        mapper.findAndRegisterModules();
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        mapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
        StringWriter stringWriter = new StringWriter();
        try {
            mapper.writeValue(stringWriter, object);
            return stringWriter.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * (此方法非必要)
     * json 2 yaml
     * @param jsonStr json
     * @return yaml
     * @throws JsonProcessingException Exception
     */
    public static String json2Yaml(String jsonStr) throws JsonProcessingException {
        JsonNode jsonNode = new ObjectMapper().readTree(jsonStr);
        return new YAMLMapper().writeValueAsString(jsonNode);
    }
}

第三步:代码演示

在测试类进行简单演示!

package com.zibo.api;

import com.zibo.api.util.YamlUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zibo
 * @date 2022/3/28 0028 20:35
 */
@SpringBootTest
public class MyYamlTest {
    @Test
    public void transform() {
        // 1、准备 Java 对象
        Map<String, String> map = new HashMap<>();
        map.put("k1", "v1");
        map.put("k2", "v2");
        map.put("k3", "v3");
        Cat cat = new Cat("喵喵", 2, Arrays.asList("捉老鼠", "吃鱼"), map);
        // 2、Java 对象转 yaml 字符串
        String toYaml = YamlUtil.toYaml(cat);
        System.out.println(toYaml);
        // 3、yaml 字符串转 Java 对象
        Cat toObject = YamlUtil.toObject(toYaml, Cat.class);
        System.out.println(toObject);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Cat {
    private String name;
    private Integer age;
    private List<String> hobbies;
    private Map<String, String> map;
}

第四步:运行结果

name: "喵喵"
age: 2
hobbies:
- "捉老鼠"
- "吃鱼"
map:
  k1: "v1"
  k2: "v2"
  k3: "v3"

Cat(name=喵喵, age=2, hobbies=[捉老鼠, 吃鱼], map={k1=v1, k2=v2, k3=v3})

2、使用 com.esotericsoftware.yamlbeans

第一步:在 pom.xml下引入依赖

<dependency>
    <groupId>com.esotericsoftware.yamlbeans</groupId>
    <artifactId>yamlbeans</artifactId>
    <version>1.15</version>
</dependency>

下面的和这个好像是同一个,引入效果似乎一样,具体需探索!

<!--yaml-->
<dependency>
    <groupId>com.github.sanjusoftware</groupId>
    <artifactId>yamlbeans</artifactId>
    <version>1.11</version>
</dependency>

第二步:写个工具类

package com.zibo.api.utils;

import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import com.esotericsoftware.yamlbeans.YamlWriter;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * @author zibo
 * @date 2022/3/28 0028 22:18
 */
public class YamlUtil {
    private YamlUtil() {}

    /**
     * 将 Java 对象写到 yaml 文件
     *
     * @param object   对象
     * @param yamlPath 文件路径
     */
    public static void writeYaml(Object object, String yamlPath) {
        try {
            YamlWriter writer = new YamlWriter(new FileWriter(yamlPath));
            writer.write(object);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从 yaml 文件读取转到 Java 对象
     * @param yamlPath 文件路径
     * @param clazz    目标类.class
     * @param <T>      目标类
     * @return 目标类对象
     */
    public static <T> T readYaml(String yamlPath, Class<T> clazz) {
        try {
            YamlReader reader = new YamlReader(new FileReader(yamlPath));
            try {
                return reader.read(clazz);
            } catch (YamlException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}

第三步:写一个实体类

这个实体类的构造函数需要使用 public 修饰,我刚开始在测试类里面写的实体类无法使用!

package com.zibo.api.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
    private String name;
    private Integer age;
    private List<String> list;
    private Map<String, String> map;
}

第四步:代码测试

package com.zibo.api;

import com.zibo.api.entity.Cat;
import com.zibo.api.utils.YamlUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zibo
 * @date 2022/3/28 0028 22:58
 */
@SpringBootTest
public class YamlTest {
    @Test
    public void transform() {
        String path = "test.yaml";
        // 1、准备 Java 对象
        Map<String, String> map = new HashMap<>();
        map.put("k1", "v1");
        map.put("k2", "v2");
        map.put("k3", "v3");
        Cat cat = new Cat("喵喵", 2, Arrays.asList("捉老鼠", "吃鱼"), map);
        // 2、Java 对象写到 yaml 文件
        YamlUtil.writeYaml(cat, path);
        // 3、读取 yaml 文件转成 Java 字符串
        System.out.println(YamlUtil.readYaml(path, Cat.class));
    }
}

第五步:运行结果

test.yaml 文件

注意这里的中文转成了 Unicode 编码!

!com.zibo.api.entity.Cat
name: "\u55b5\u55b5"
age: 2
list: !java.util.Arrays$ArrayList
- "\u6349\u8001\u9f20"
- "\u5403\u9c7c"
map: 
   k1: v1
   k2: v2
   k3: v3

控制台输出

Cat(name=喵喵, age=2, list=[捉老鼠, 吃鱼], map={k1=v1, k2=v2, k3=v3})

3、使用 org.jyaml

概述

此框架不再更新,基本可以满足使用,有一点瑕疵!

参考文章

《java-yml工具类JYaml用法》 https://www.cnblogs.com/yb38156/p/14690382.html

《Yaml介绍及JYaml将数据写入yaml文件》 https://blog.csdn.net/m0_37739193/article/details/78690680

《JYaml——>Yaml的Java实现》 https://www.cnblogs.com/adderhuang/p/11524975.html

参考网站

http://jyaml.sourceforge.net/tutorial.html

4、使用 SnakeYaml

第一步:在 pom.xml 下引入依赖

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.30</version>
</dependency>

第二步:写一个工具类

package com.zibo.api.utils;

import org.yaml.snakeyaml.Yaml;

import java.io.StringWriter;

/**
 * @author zibo
 * @date 2022/3/28 0028 22:18
 */
public class YamlUtil2 {
    private YamlUtil2() {
    }

    /**
     * Java 对象转 yaml 字符串
     * @param object 对象
     * @return 字符串
     */
    public static String toYaml(Object object) {
        Yaml yaml = new Yaml();
        StringWriter sw = new StringWriter();
        yaml.dump(object, sw);
        return sw.toString();
    }

    /**
     * 从 yaml 文件读取转到 Java 对象
     * @param yamlStr yaml 字符串
     * @param clazz   目标类.class
     * @param <T>     目标类
     * @return 目标类对象
     */
    public static <T> T toObject(String yamlStr, Class<T> clazz) {
        Yaml yaml = new Yaml();
        return yaml.loadAs(yamlStr, clazz);
    }

}

第三步:写一个实体类

package com.zibo.api.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
    private String name;
    private Integer age;
    private List<String> list;
    private Map<String, String> map;
}

第四步:代码测试

package com.zibo.api;

import com.zibo.api.entity.Cat;
import com.zibo.api.utils.YamlUtil2;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zibo
 * @date 2022/3/28 0028 22:58
 */
@SpringBootTest
public class YamlTest {
    @Test
    public void transform() {
        // 1、准备 Java 对象
        Map<String, String> map = new HashMap<>();
        map.put("k1", "v1");
        map.put("k2", "v2");
        map.put("k3", "v3");
        Cat cat = new Cat("喵喵", 2, Arrays.asList("捉老鼠", "吃鱼"), map);
        // 2、Java 对象转 yaml 字符串
        String yaml = YamlUtil2.toYaml(cat);
        System.out.println(yaml);
        // 3、读取 yaml 文件转成 Java 字符串
        System.out.println(YamlUtil2.toObject(yaml, Cat.class));
    }
}

第五步:运行结果

!!com.zibo.api.entity.Cat
age: 2
list: [捉老鼠, 吃鱼]
map: {k1: v1, k2: v2, k3: v3}
name: 喵喵

Cat(name=喵喵, age=2, list=[捉老鼠, 吃鱼], map={k1=v1, k2=v2, k3=v3})
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值