詳解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"
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章