配置
忽略不认识的字段
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
这样是配置在整个ObjectMapper上的,如果只希望配置在某个类上面,可以使用@JsonIgnoreProperties(ignoreUnknown=true)
注解使用
忽略NULL字段
实体类上使用
// 过NULL字段,但是过期了
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
// 现在推荐使用该方式
@JsonInclude(JsonInclude.Include.NON_NULL)
如果使用在类上,那么对该类中的所有字段都起作用
如果只使用到某个字段上,那么只是对该字段起作用
参数意义:
JsonInclude.Include.ALWAYS 默认
JsonInclude.Include.NON_DEFAULT 属性为默认值不序列化
JsonInclude.Include.NON_EMPTY 属性为 空(””) 或者为 NULL 都不序列化
JsonInclude.Include.NON_NULL 属性为NULL 不序列化
配置文件中
这里以springboot为例,在yml中配置全局定义
spring:
jackson:
default-property-inclusion: non_null
忽略序列化
json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。
// 此注解用于属性或者方法上(最好是属性上)
@JsonIgnore
// 此注解是类注解, 在此指定忽略name,age字段
@JsonIgnoreProperties({"name"},{"age"})
public class user {
private String name;
private int age;
private String address;
}
引用同一个对象
我们看个简单的例子,有两个类Common和A,A中有两个Common对象,如下:
static class Common {
public String name;
}
static class A {
public Common first;
public Common second;
}
现在新建一个对象A和Common,将first和second都指向同一个common
Common c = new Common();
= "common";
A a = new A();
a.first = a.second = c
此时使用jackson序列化a后输入为
{
"first": {
"name": "common"
},
"second": {
"name": "common"
}
}
但是在反序列化后,first和second将指向不同的对象。
此时可以使用注解@JsonIdentityInfo
解决循环引用
假设有一个Parent类和一个Child类,它们相互引用
static class Parent {
public String name;
public Child child;
}
static class Child {
public String name;
public Parent parent;
}
相互引用如下
Parent p = new Parent();
= "父亲";
Chilc c = new Child();
= "儿子";
p.child = c;
c.parent = p;
如果用jackson序列化p这个对象,jackson会进入无限循环最终抛出异常。
解决这个问题,可以分别标记Parent类中的child和Child类中的parent字段,将其中一个标记为主引用,另一个标记为反向引用,主引用用@JsonManagedReference
,反向引用使用@JsonBackReference
继承和多态
Jackson不能自动处理多态的情况。
static class Shape {}
static class Circle extends Shape {
private int r;
}
static class Square extends Shape {
private int l;
}
static class ShapeManager {
private List<Shape> shapes;
}
ShapeManager中的Shape列表中的对象可能是Circle,也可能是Square。如:
ShapeManager sm = new ShapeManager();
List<Shape> shapes = new ArrayList<Shape>();
shapes.add(new Circle(10));
shapes.add(new Square(5));
sm.setShapes(shapes);
此时将sm序列化输出为:
{
"shapes":[{
"r": 10
}, {
"l": 5
}]
}
这个输出看上去是没有问题的,但是由于输出中没有类型信息,反序列化时,Jackson不知道具体的Shape类型是什么,就会抛出异常。
解决办法就是在输出中包含类型信息,在基类Shape前使用如下注解:
@JsonTypeInfo(use = , include = As.PROPERTY, property = "TYPE")
@JsonSubTypes({
@JsonSubTypes.Type(value = Circle.class, name="circle"),
@JsonSubTypes.Type(value = Square.class, name="square")})
static class Shape {
}
含义是在输出中增加属性”type”,表示对象的实际类型,对Circle类,使用”circle”表示其类型,而对Square类,使用”square”。加了注解后,序列化输出变成:
{
"shapes":[{
"type": "circle",
"r": 10
}, {
"type": "square",
"l": 5
}]
}
修改字段名
如果我们希望输出的字段名变为对应的中文
public class Student {
@JsonProperty("姓名");
String name;
}
日期时间格式化
@JsonSerialize(using = Date2LongSerializer.class)
java中JsonSerializer用法,前后端单位转换必备
@JsonFormat(pattern="yyyy-MM-dd HH:mm", timezone="GMT+8")
private Date regisDate;