详解jackson注解(一)jackson系列化注解

详解jackson注解(一)jackson系列化注解

jackson中用于系列化的主要注解有:

注解描述
1@JsonAnyGetter@JsonAnyGetter注解可以灵活地把类型为Map的属性作为标准属性使用。
2@JsonGetter@JsonProperty注解的替代方法,用于将方法标记为getter方法。
3@JsonPropertyOrder指定系列化时各个属性的顺序
4@JsonRawValue可以指示Jackson完全按原样序列化属性
5@JsonValue@JsonValue 可以用在get方法或者属性字段上,一个类只能用一个,当加上@JsonValue注解时,序列化是只返回这一个字段的值。
6@JsonRootName如果启用了包装,使用@JsonRootName注解指定要使用的根包装的名称。

上面的这些描述有一些可能不容易理解,看看下面的案例就理解了。

(一)@JsonAnyGetter

@JsonAnyGetter注解可以灵活地把类型为Map的属性作为标准属性使用。

1、在bean的map属性上添加@JsonAnyGetter注解:

import com.fasterxml.jackson.annotation.JsonAnyGetter;

import java.io.Serializable;
import java.util.Map;

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
public class User implements Serializable {

    public String name;

    private Map<String, String> properties;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // 在map属性上添加@JsonAnyGetter
    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public User() {
    }

    public User(String name) {
        this.name = name;
    }
}

2、controller中:

@GetMapping("/test1")
public User test() {
    User user = new User("小明");
    Map<String,String> map = new HashMap<String,String>();
    map.put("age", "120");
    map.put("address", "中国");
    user.setProperties(map);
    return user;
}

3、使用Postman请求,得到的响应:

{
    "name": "小明",
    "address": "中国",
    "age": "120"
}

将bean的map中的属性都提取出来当做了bean的标准属性。好处就是灵活,不改bean的前提下可以灵活地设置系列化属性。

(二)@JsonGetter

@JsonProperty注解的替代方法,用于将方法标记为getter方法。

public class User {
    public int id;
    
    private String name;
 
    @JsonGetter("name")
    public String getTheName() {
        return name;
    }
    
    // ......
}

(三)@JsonPropertyOrder

指定系列化时各个属性的顺序

1、bean

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

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@Data
// 指定各个属性在系列化时的顺序
@JsonPropertyOrder({"name", "email", "phone", "address"})
public class User {
    private String name;
    private String address;
    private String email;
    private String phone;
}

2、controller

@GetMapping("/test2")
public User test2() {
    User user = new User();
    user.setName("chushiyan");
    user.setEmail("chushiyan0415#163.com");
    user.setPhone("18812345678");
    user.setAddress("中国");
    return user;
}

响应的json按照了@JsonPropertyOrder指定的顺序:

{
    "name": "chushiyan",
    "email": "chushiyan0415#163.com",
    "phone": "18812345678",
    "address": "中国"
}

(四)@JsonRawValue

可以指示Jackson完全按原样序列化属性

1、bean

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

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@Data
public class Admin {
    public String name;

    @JsonRawValue
    public String json;
}

2、controller

 @GetMapping("/test5")
    public Admin test5(){
        Admin admin = new Admin();
        admin.setName("chushiyan");
        admin.setJson("{\"attr\":true}");
        return admin;
    }

postman请求返回的响应:

{
    "name": "chushiyan",
    "json": {
        "attr": true
    }
}

(五)@JsonValue

@JsonValue 可以用在get方法或者属性字段上,一个类只能用一个,当加上@JsonValue注解时,序列化是只返回这一个字段的值。

1、bean

import com.fasterxml.jackson.annotation.JsonValue;

import java.io.Serializable;
import lombok.Data;

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@Data
public class Student implements Serializable {

    private String name;

    @JsonValue
    private Integer score;
}

2、controller

 @GetMapping("/test6")
    public Student getStudent() {
        Student student = new Student();
        student.setName("chushiyan");
        student.setScore(60);
        return student;
    }

3、postman请求返回的响应

60

注意:一个bean只能使用@JsonValue注解一个属性,注解多个就会报错:

com.fasterxml.jackson.databind.JsonMappingException: Problem with definition of [AnnotedClass com.chushiyan.test.entity.Student]: Multiple 'as-value' properties defined ([field com.chushiyan.test.entity.Student#name] vs [field com.chushiyan.test.entity.Student#score])

(六)@JsonRootName

如果启用了包装,使用@JsonRootName注解指定要使用的根包装的名称。

例如,定义一个People类,通常系列化后是这样的:

{
    "id": "1",
    "name": "chushiyan"
}

如果想系列化下面这个样子呢?

{
    "people": {
        "id": "1",
        "name": "chushiyan"
    }
}

这时,就可以使用@JsonRootName了。

1、bean

import com.fasterxml.jackson.annotation.JsonRootName;

/**
 * @author chushiyan
 * @email  Y2h1c2hpeWFuMDQxNUAxNjMuY29t(base64)
 * @description
 */
@Data
@JsonRootName(value = "people")  // 默认是类名
public class People {
    
    private String id;
    
    private String name;

}

2、controller

@GetMapping("/people")
public People test3() {
    People people = new People("1", "chushiyan");
    return people;
}

然而,响应的结果不是我们希望的:

{
    "id": "1",
    "name": "chushiyan"
}

因为还需要相应的配置,因为使用@JsonRootName的前提就是启用了包装:

spring.jackson.serialization.wrap-root-value=true

或者yml中:

spring:
  jackson:
    serialization:
      wrap-root-value: true

再次请求,返回的结果就是我们需要的了。

{
    "people": {
        "id": "1",
        "name": "chushiyan"
    }
}

注意:一旦在配置了spring.jackson.serialization.wrap-root-value=true,所有的响应都成了这种json样式,哪怕报错了:

{
    "Map": {
        "timestamp": "2019-12-01T07:36:50.164+0000",
        "status": 404,
        "error": "Not Found",
        "message": "No message available",
        "path": "/test/people1"
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值