详解jackson注解(三)jackson包含属性、忽略属性的注解

详解jackson注解(三)jackson包含属性、忽略属性的注解

jackson中,指定包含哪些属性、忽略哪些属性的注解:

注解类 描述
1 JsonIgnoreProperties 用于标记忽略一个或多个属性。可以注解在类上、构造函数、方法、字段上。
2 JsonIgnore @JsonIgnore注解用于在字段级别标记要忽略的属性。注意:系列化和反系列化时都会被忽略。
3 JsonInclude 使用@JsonInclude可以只包含非空的属性,也即排除值为empty、null的属性。
4 JsonAutoDetect 默认情况下,jackson获取public权限的字段进行系列化和反系列化。如果没有public修饰的字段,就会去获取public修饰的getter/setter。使用 JsonAutoDetect注解,我们就可以修改默认的行为。

一、JsonIgnoreProperties

用于标记忽略一个或多个属性。可以注解在类上、构造函数、方法、字段上。

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 * @author chushiyan
 * @email  chushiyan0415@163.com
 * @description 自关联的权限表。一个权限有一个父权限、多个子权限
 */
@Data
public class Permission implements Serializable {

    private String id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "permission_parent_id", referencedColumnName = "permission_id")
    private Permission parent;

    // 必须使用JsonIgnoreProperties忽略parent属性
    // 否则查询到子权限,子权限有parent属性,又去查父权限,会导致系列化时出现死循环
    @JsonIgnoreProperties(value = "parent")
    @OneToMany(mappedBy = "parent")
    private Set<Permission> children = new HashSet<Permission>();
   
}

二、JsonIgnore

@JsonIgnore注解用于在字段级别标记要忽略的属性。注意:系列化和反系列化时都会被忽略。

1、bean

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.io.Serializable;

/**
 * @author chushiyan
 * @email  chushiyan0415@163.com
 * @description
 */
@Data
public class Article implements Serializable {

    private String id;

    private String name;

    @JsonIgnore
    private String category;
}

2、测试

    @Test
    public void testJsonIgnore() throws JsonProcessingException {
        String json = "{"
                + "\"id\" : \"100\","
                + "\"name\" : \"详解jackson注解","
                + "\"category\" : \"jackson\""
                + "}";
        ObjectMapper mapper = new ObjectMapper();
        Article article = mapper.readValue(json,Article.class);
        System.out.println(article);

        Article article2 = new Article();
        article2.setId("100");
        article2.setName("详解jackson注解");
        article2.setCategory("jackson");
        String json2 = mapper.writeValueAsString(article2);
        System.out.println(json2);
}

3、控制台输出

Article(id=100, name=详解jackson注解, category=null)
{"id":"100","name":"详解jackson注解"}

反系列化时,json数据中明明包含了category值,但是最后Article对象的category属性值依然为null。就是因为使用了JsonIgnore。

三、JsonInclude

我们可以使用@JsonInclude排除某些empty、null、默认值的属性。

import com.fasterxml.jackson.annotation.JsonInclude;

/**
 * @author chushiyan
 * @email chushiyan0415@163.com
 * @description
 */
// 使用JsonInclude注解指明只包含非null的属性,即排除值为null的属性
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result {

    private boolean flag;// 是否成功

    private Integer code;// 返回码

    private String message;// 返回信息

    private Object data;// 返回数据

    public Result() {
    }

    public Result(boolean flag, Integer code, String message) {
        this.flag = flag;
        this.code = code;
        this.message = message;
    }

    public Result(boolean flag, Integer code, String message, Object data) {
        this.flag = flag;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
    
    @Override
    public String toString() {
        return "Result{" +
                "flag=" + flag +
                ", code=" + code +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }

}

2、controller

    @GetMapping("/test8")
    public Result testJsonInclude(){
        return new  Result(true,200,"查询成功");
    }

没有在Result类上加 @JsonInclude(JsonInclude.Include.NON_NULL) 注解时,返回的响应:

{
    "flag": true,
    "code": 200,
    "message": "查询成功",
    "data": null
}

加了之后的返回的响应:

{
    "flag": true,
    "code": 200,
    "message": "查询成功"
}

四、 JsonAutoDetect

默认情况下,jackson获取public权限的字段进行系列化和反系列化。如果没有public权限的字段,就会去获取public修饰的getter/setter。使用 JsonAutoDetect注解,我们就可以修改默认的行为。比如,下面的案例,即使字段都是private的、也没有getter/setter,也照样获取字段。

1、bean

首先,我们定义一个属性id/name都私有的而且没有getter/setter的一个bean

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import java.io.Serializable;

/**
 * @author chushiyan
 * @email chushiyan0415@163.com
 * @description
 */
//@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class PrivateBean implements Serializable {

    private String id;

    private String name;

    public PrivateBean() {
    }

    public PrivateBean(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "PrivateBean{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

2、反系列化测试:

    @Test
    public void testJsonAutoDetect() throws JsonProcessingException {
        String json = "{"
                + "\"id\" : \"10\","
                + "\"name\" : \"chushiyan\""
                + "}";
        ObjectMapper mapper = new ObjectMapper();
        PrivateBean bean = mapper.readValue(json, PrivateBean.class);
        System.out.println(bean);
    }

报错:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "id" (class com.chushiyan.test.entity.PrivateBean), not marked as ignorable (0 known properties: ])
 at [Source: (String)"{"id" : "10","name" : "chushiyan"}"; line: 1, column: 10] (through reference chain: com.chushiyan.test.entity.PrivateBean["id"])

3、系列化测试

    @Test
    public void testJsonAutoDetect2() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        PrivateBean bean = new PrivateBean("11", "chushiyan");
        String json = mapper.writeValueAsString(bean);
        System.out.println(json);
    }

报错:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.chushiyan.test.entity.PrivateBean and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

4、bean上加上注解

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import java.io.Serializable;

/**
 * @author chushiyan
 * @email chushiyan0415@163.com
 * @description
 */
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class PrivateBean implements Serializable {

    private String id;

    private String name;

    public PrivateBean() {
    }

    public PrivateBean(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "PrivateBean{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

5、再次分别测试反系列化、系列化

都运行正常,分别打印:

PrivateBean{id='10', name='chushiyan'}
{"id":"11","name":"chushiyan"}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容

  • Jackson JSON工具包包含一组Java注释,您可以使用它们来影响如何将JSON读入对象,或者从对象生成JS...
    谁在烽烟彼岸阅读 7,218评论 0 6
  • spring官方文档:http://docs.spring.io/spring/docs/current/spri...
    牛马风情阅读 1,670评论 0 3
  • Java生态圈中有很多处理JSON和XML格式化的类库,Jackson是其中比较著名的一个。虽然JDK自带了XML...
    乐百川阅读 28,061评论 6 23
  • JPA的注解 1.@MappedSuperclass1)@MappedSuperclass注解只能标准在类上:@T...
    廖马儿阅读 2,129评论 0 2
  • 当夜幕降临的时候, 想到你的样子, 忍不住, 笑了起来, 无论, 睡着还是醒着...... 闭上双眼, 到处都是你...
    采蘑菇的小兔阅读 155评论 0 0