在日常开发中,经常利用JSON作为数据传输的格式,为此JSON序列化(将对象转换为JSON字符串)和反序列化(将JSON字符串转换指定的数据类型)经常用到。
本文主要介绍利用fasterxml.jackson实现JSON序列化和反序列化,并针对碰到到Unrecognized field
的问题进行解决。
利用fasterxml.jackson依赖jackson-core, jackson-databind和jackson-annotations,在build.gradle文件中添加依赖, 示例如下:
dependencies {
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.5'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.5'
}
我们构造一个JSON工具类,实现JSON序列化和反序列化, 主要用到的类为com.fasterxml.jackson.databind.ObjectMapper
, 代码示例如下:
package com.notepad.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
/**
* Created by YM on 2017/6/11.
*/
public class JsonSerializer {
/**
* JSON序列化
*
* @param object 对象
* @return JSON字符串
*/
public static String serialize(Object object) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
return "";
}
}
/**
* JSON字符串反序列化
*
* @param jsonStr JSON字符串
* @return a Map
*/
public static Map deserialize(String jsonStr) {
try {
return deserialize(jsonStr, Map.class);
} catch (Exception e) {
e.printStackTrace();
return new HashMap();
}
}
public static T deserialize(String jsonStr, Class classType) throws Exception {
return new ObjectMapper().readValue(jsonStr, classType);
}
}
为测试我们编写的JSON工具类, 定义一个Entity对象。
为了构建的Entity对象被JSON工具类操作, 关于Entity有几点说明:
可选:可通过@JsonIgnore注解,过滤掉不需要进行序列化的成员变量。
示例如下:
package com.notepad.thinkingnote.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Description: 实体定义
*
* Create: 2018/9/6 22:37
*
* @author Yang Meng
*/
public class Entity {
public Entity() {}
public Entity(String uid, String name) {
this.uid = uid;
this.name = name;
}
/** 实体标识符 */
@JsonProperty("UID")
private String uid;
@JsonProperty("name")
private String name;
public void setUid(String uid) {
this.uid = uid;
}
public String getUid() {
return uid;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
编写单元测试,测试Entity的序列化和反序列化, 示例如下:
package com.notepad.thinkingnote.domain;
import com.notepad.util.JsonSerializer;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Description: 实体序列化和反序列化单测
*
* Create: 2018/9/6 22:41
*
* @author Yang Meng
*/
public class EntityTest {
@Test
public void testSerialize() throws Exception {
Entity entity = new Entity("James", "James");
System.out.println(JsonSerializer.serialize(entity));
}
@Test
public void testDeserialize() throws Exception {
String test = "{\"UID\":\"James\",\"name\":\"James\"}";
Entity entity = JsonSerializer.deserialize(test, Entity.class);
System.out.println(entity.getUid() + ":" + entity.getName());
}
}
输出结果如下:
// entity的序列化结果, 显示字段UID
{"UID":"James","name":"James"}
// entity的序列化结果
James:James
通过上面的介绍, 我们基本了解了JSON的序列化和反序列化,不过有时我们会遇到一种问题。
考虑这样一种情况,我们针对Http接口返回的JSON字符串,构建了一个具体的Entity对象,但是Http接口中突然增加了一个字段type,如果按照上述的方法构造,这时会出现什么问题?
再编写一个单测样例:
@Test
public void testDeserialize() throws Exception {
String test = "{\"UID\":\"James\",\"name\":\"James\", \"type\":\"entity\"}";
Entity entity = JsonSerializer.deserialize(test, Entity.class);
System.out.println(entity.getUid() + ":" + entity.getName());
}
出现UnrecognizedPropertyException异常:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" ....
即对于新添加的type字符无法识别。如何解决这个问题呢?我们这里提供2种方法。
利用fasterxml.jackson提供的@JsonIgnoreProperties注解,针对无法识别的属性进行过滤。这里主要是修改需要进行反序列化的对象Entity,示例如下:
// 针对无法识别的属性进行过滤
@JsonIgnoreProperties(ignoreUnknown = true)
public class Entity {...}
方法1的修改需要对每一个需要进行反序列化的类进行修改, 不太方便。
方法2通过修改JSON工具类的反序列化方法,设置DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES的值为false, 可以仅一次修改就适用全部对象。
示例如下:
public static T deserialize(String jsonStr, Class classType) throws Exception {
// 添加configure, 设置DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES为false
// 则对于无法识别的属性直接过滤
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(jsonStr, classType);
}
本文主要介绍利用jackson实现Json序列化和反序列化,并给出了解决UnrecognizedPropertyException异常的2种方法。