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