Json与Object之间互相转换工具——Jackson 高性能的JSON处理 ObjectMapper

于飞飙
2023-12-01

应用场景

       在项目开发过程中,很多时候移动终端设备都要与服务器进行数据交互。两者之间的数据格式通常为 JSON 和 XML。而这些数据通常都跟我们的Model(Java 中常被称作bean)是一一对应的,在成功接收到从服务器返回过来的数据后,我们可以将 JSON 数据当作一个个的键值对然后进行解析,虽然这也算是一种解决方式,但一定程度上加大开发者的工作量。当需要将 JSON 数据快速的解析成一个 Object,那么选择第3方框架ObjectMapper是个不错的选择。

 

ObjectMapper介绍(与android中的Gson框架类似)

ObjectMapper 是一个基于 Swift 语言开发的能够让 JSON 与 Object 之间轻易转换的类库。通过 ObjectMapper 我们可以将 JSON 数据转换成 Model 对象或将 Model 对象转换成 JSON 数据。

官方描述:

ObjectMapper is a framework written in Swift that makes it easy for you to convert your model objects (classes and structs) to and from JSON.

 

ObjectMapper在github上的地址

https://github.com/Hearst-DD/ObjectMapper

 

ObjectMapper 有如下几大特点:

  • Mapping JSON to Object(JSON 映射成对象)
  • Mapping Object to JSON(对象转换成 JSON)
  • Nested Object(支持内嵌对象功能,包括数据和字典)
  • Support Struct(也对结构体做了支持)

官方介绍ObjectMapper可以解析web api中的json数据,也可以与Realm数据库配合使用

  • ObjectMapper + Alamofire
  • ObjectMapper + Realm

 

ObjectMapper使用测试

创建两个简单的Bean用于测试,省去get/set/toString

public class Tuser implements Serializable{
    private static final long serialVersionUID = 1L;
    private String name;
    private Integer age;
    private List joinClass;
}

public class Tclass implements Serializable {
    private static final long serialVersionUID = 1L;
    private String className;
    private Date classTime;
}

封装为工具类方便调用 

package com;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
import java.text.SimpleDateFormat;

public class JacksonUtils {

    private static ObjectMapper mapper = new ObjectMapper();

    static {
        try {
            // 以下可以自定义ObjectMapper的一些属性
            mapper.getJsonFactory().createJsonGenerator(System.out, JsonEncoding.UTF8);
            // 设置日期格式化(24小时)
            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            // 设置输入时忽略JSON字符串中存在而Java对象实际没有的属性,若不忽略会报错:Unrecognized field "xxx"
            // mapper.getDeserializationConfig().set(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 已过时
            objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
            // 忽略反斜杠,默认为不忽略
            mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
            // Inclusion.ALWAYS 创建输出全部属性到Json字符串
            // Include.NON_DEFAULT 属性为默认值不序列化
            // Inclusion.NON_DEFAULT 属性为:空(""),或者为NULL,都不序列化
            // Include.NON_NULL 属性为NULL,不序列化
            mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
            // 设置可以序列化集合
            mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Json字符串 ---> 实体对象
     *
     * @param json
     * @param clazz 实体对象所属类Class
     * @return
     */
    public static <T> T json2Object(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * 定制化返回数据结构,例List<bean> or other
     * Map<String,String> ext = JSON.parseObject(extStr,new TypeReference<Map<String, String>>(){});
     */
    public static <T> T json2Object(String json, TypeReference<T> typeReference) {
        try {
            return mapper.readValue(json, typeReference);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * 实体对象 ---> Json字符串
     *
     * @param t 实体对象T
     * @return T
     */
    public static <T> String object2Json(T t) {
        try {
            return mapper.writeValueAsString(t);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }
}
package com;

import org.codehaus.jackson.type.TypeReference;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class Test {

    public static void main(String[] args) {
//        TODO 单个对象转换 测试开始
        List<Tclass> joinClass = new ArrayList<>();
        for (int i = 0; i<2; i++) {
            Tclass c = new Tclass();
            c.setClassName("课程" + (i + 1));
            c.setClassTime(new Date());
            joinClass.add(c);
        }
        Tuser u1 = new Tuser();
        u1.setName("小明");
        u1.setAge(6);
        u1.setJoinClass(joinClass);

        String json = JacksonUtils.object2Json(u1);
        System.out.println(json); // {"name":"小明","age":6,"joinClass":[{"className":"课程1","classTime":"2019-09-25 17:29:48"},{"className":"课程2","classTime":"2019-09-25 17:29:48"}]}

        Tuser tuser1 = JacksonUtils.json2Object(json, Tuser.class);
        System.out.println("tuser1--->" + tuser1.toString()); // 基于上面的json转换回对象成功
        // 将对象结构转为:Map<String, Object>
        Map<String, Object> tuserListBack = JacksonUtils.json2Object(json, new TypeReference<Map<String, Object>>() {});
//        TODO 单个对象转换 测试结束


//        TODO 对象集合Json转换 测试开始
        Tuser u2 = new Tuser();
        u2.setName("小虹");
        u2.setAge(8);
        u2.setJoinClass(joinClass);
        List<Tuser> tuserList = new ArrayList<>();
        tuserList.add(u1);
        tuserList.add(u2);
        String json2 = JacksonUtils.object2Json(tuserList);
        System.out.println(json2);

        // 1,转为List<Tuser>结构
        List<Tuser> tuserListBack1 = JacksonUtils.json2Object(json2, new TypeReference<List<Tuser>>() {});
        System.out.println("tuserListBack2--->" + tuserListBack1.toString());
        // 2,自定义返回:转为List<Map<String, Object>>结构
        List<Map<String, Object>> tuserListBack2 = JacksonUtils.json2Object(json2, new TypeReference<List<Map<String, Object>>>() {});
        System.out.println("tuserListBack2--->" + tuserListBack2.toString());
    }
}

 

上面的静态代码块里有一句,统一设置:对象属性为NULL,不参与序列化

// 注意:只对VO起作用;对Map List不起作用,序列化Map List时,属性为null依旧会被序列化
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);

 这和实体上单独增加注解功能一致:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 

 


参考来源于:

https://www.jianshu.com/p/8d7442ed328b

https://blog.csdn.net/liuxiao723846/article/details/46043933

https://blog.csdn.net/weixin_42047790/article/details/83541018

 类似资料: