偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java 如何序列化不固定的 JSON 字段

開發(fā) 前端
起初我以為只能通過 Map 手動解析,但后來發(fā)現(xiàn) Jackson 提供了?@JsonAnyGetter?和?@JsonAnySetter?這兩個注解,專門用來處理這種“動態(tài)屬性”。它們能讓我優(yōu)雅地把未知字段收集起來或者序列化出去,不影響已知字段的正常處理。

最近在處理一個 JSON 接口時,遇到這樣一種情況:返回的數(shù)據(jù)中包含一些我事先并不知道的字段,這些字段會根據(jù)上下文動態(tài)變化,沒辦法在 Java 類中提前寫死字段名。

起初我以為只能通過 Map 手動解析,但后來發(fā)現(xiàn) Jackson 提供了 @JsonAnyGetter 和 @JsonAnySetter 這兩個注解,專門用來處理這種“動態(tài)屬性”。它們能讓我優(yōu)雅地把未知字段收集起來或者序列化出去,不影響已知字段的正常處理。

不過我在使用過程中也有點疑惑,比如這兩個注解的用法順序有什么講究?有哪些坑需要避免?這種方式是不是適合所有動態(tài)字段的場景?

開家雜貨鋪吧

@JsonAnyGetter/@JsonAnySetter: 像開了一家靈活應(yīng)對一切需求的「雜貨鋪」????

想象你是個 JSON 雜貨鋪老板,門口寫著招牌:“你有啥,我都能裝;你要啥,我都能配?!?/p>

你平時會備一些常規(guī)商品(字段),但總有顧客帶些奇怪需求來問:

  • “老板,有沒有草莓味的牙膏?”
  • “能不能加點冰塊到辣醬里?”

這些你事先沒在貨架上準(zhǔn)備的“臨時需求”,你也得接單,對吧?

這時候你就需要一對“萬能架子”——也就是:

@JsonAnySetter:隨便放!你給啥我都能接

每次有奇怪字段進(jìn)來(JSON 反序列化時),你就把它們統(tǒng)統(tǒng)放進(jìn)一個萬能柜子(通常是 Map<String, Object>):

@JsonAnySetter
public void add(String key, Object value) {
    otherProps.put(key, value);
}

比如這個 JSON:

{
  "name": "豆瓣醬",
  "spicy": true,
  "limited_edition": "yes",
  "extra_notes": "只在冬天賣"
}

你類里只定義了 name 和 spicy 字段,但 limited_edition 和 extra_notes 也能順利進(jìn)貨,被收納進(jìn)了 otherProps 這個萬能抽屜里。

@JsonAnySetter 用于標(biāo)注一個方法,該方法可以接收 JSON 中沒有預(yù)定義的屬性。當(dāng) Jackson 反序列化 JSON 時,如果遇到未在 Java 類中顯式定義的字段,它會調(diào)用這個方法并將字段名和字段值作為參數(shù)傳遞給它。

當(dāng)你在反序列化 JSON 時,不希望顯式定義所有的字段,或者 JSON 中包含了動態(tài)的屬性時,使用 @JsonAnySetter 可以自動將這些字段添加到一個 Map 或類似的結(jié)構(gòu)中。

接下來用一個完整的代碼示例,我們來實現(xiàn)反序列化時動態(tài)添加屬性:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

publicclass Person {
    private String name;
    privateint age;

    // 存儲額外的動態(tài)屬性
    private Map<String, Object> additionalProperties = new HashMap<>();

    // 添加動態(tài)屬性
    @JsonAnySetter
    public void addAdditionalProperty(String key, Object value) {
        this.additionalProperties.put(key, value);
    }

    // 省略 getter 和 setter 方法

    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }

    public static void main(String[] args) throws Exception {
        String json = "{"name":"John","age":30,"address":"123 Street","nickname":"Johnny"}";

        ObjectMapper mapper = new ObjectMapper();
        Person person = mapper.readValue(json, Person.class);

        System.out.println("Name: " + person.name);  // 輸出:Name: John
        System.out.println("Age: " + person.age);    // 輸出:Age: 30
        System.out.println("Additional Properties: " + person.getAdditionalProperties());
        // 輸出:Additional Properties: {address=123 Street, nickname=Johnny}
    }
}

在這個例子中:

  • Person 類通過 @JsonAnySetter 注解的 addAdditionalProperty 方法來處理動態(tài)的屬性。
  • Person 類中沒有顯式的字段來接收 address 和 nickname,但它們被添加到 additionalProperties 中。
  • 當(dāng) Jackson 反序列化 JSON 時,它會把 address 和 nickname 作為動態(tài)屬性添加到 additionalProperties 中。

輸出:

Name: John
Age: 30
Additional Properties: {address=123 Street, nickname=Johnny}

@JsonAnyGetter:隨便拿!需要啥我都能給

到了序列化的時候,有顧客問你:“老板,這罐醬料里都包含什么成分?”

你就把主料(已有字段)和萬能抽屜里的額外信息一起打包給他,看起來就像全是標(biāo)準(zhǔn)字段一樣輸出!

@JsonAnyGetter
public Map<String, Object> getOtherProps() {
    return otherProps;
}

這樣序列化輸出的 JSON 會自動把 otherProps 里的內(nèi)容平鋪出去,和其他字段“融為一體”。

@JsonAnyGetter 用于標(biāo)注一個方法,該方法返回一個 Map 或類似結(jié)構(gòu),它將包含對象的 動態(tài)屬性(即對象中沒有顯式定義的字段)。當(dāng) Jackson 序列化對象時,它會將這個 Map 中的鍵值對當(dāng)作額外的 JSON 屬性來序列化。

當(dāng)你有一個類,但是它可能會接受動態(tài)的字段,或者一些額外的鍵值對時,使用 @JsonAnyGetter 允許你將這些額外的字段序列化為 JSON。

繼續(xù)使用上面的person類,它有一些基本的屬性,但你希望允許動態(tài)添加額外的屬性,如額外的 "address" 、 "nickname" 等字段。

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

publicclass Person {
    private String name;
    privateint age;

    // 存儲額外的動態(tài)屬性
    private Map<String, Object> additionalProperties = new HashMap<>();

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 通過該方法返回所有額外的動態(tài)屬性
    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }

    public void addAdditionalProperty(String key, Object value) {
        this.additionalProperties.put(key, value);
    }

    // 省略 getter 和 setter 方法
}

publicclass Main {
    public static void main(String[] args) throws Exception {
        Person person = new Person("John", 30);
        person.addAdditionalProperty("address", "123 Street");
        person.addAdditionalProperty("nickname", "Johnny");

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(person);
        System.out.println(json);  // 輸出:{"name":"John","age":30,"address":"123 Street","nickname":"Johnny"}
    }
}

在這個例子中:

  • Person 類包含一個 Map<String, Object> 來存儲動態(tài)屬性。
  • 使用 @JsonAnyGetter 標(biāo)注 getAdditionalProperties() 方法,表示 additionalProperties 中的鍵值對應(yīng)該被序列化為 JSON 字段。
  • 通過調(diào)用 addAdditionalProperty() 方法向 additionalProperties 中添加動態(tài)字段。

輸出:

{
  "name": "John",
  "age": 30,
  "address": "123 Street",
  "nickname": "Johnny"
}

總結(jié)一下!

圖片圖片

特別適合那些字段不固定、可能需要動態(tài)擴展的 JSON 數(shù)據(jù)結(jié)構(gòu),比如配置項、參數(shù)列表、插件信息等。

責(zé)任編輯:武曉燕 來源: 一安未來
相關(guān)推薦

2025-06-03 01:22:00

JavaJSON字段

2013-03-11 13:55:03

JavaJSON

2009-07-29 13:39:02

JSON序列化和反序列ASP.NET AJA

2018-03-19 10:20:23

Java序列化反序列化

2021-11-18 07:39:41

Json 序列化Vue

2016-10-20 15:54:08

Python數(shù)據(jù)序列化

2009-06-14 22:01:27

Java對象序列化反序列化

2018-01-17 16:38:07

MSONJSON序列化

2011-06-01 15:05:02

序列化反序列化

2022-08-06 08:41:18

序列化反序列化Hessian

2010-03-19 15:54:21

Java Socket

2010-01-08 11:11:38

JSON 序列化

2024-10-07 08:26:53

2011-04-02 09:04:49

Java序列化

2020-12-24 18:46:11

Java序列化編程語言

2009-08-24 17:14:08

C#序列化

2024-01-30 13:32:51

JSON反序列化序列化

2011-06-01 14:26:11

序列化

2011-03-04 09:25:51

Java序列化

2012-04-13 10:45:59

XML
點贊
收藏

51CTO技術(shù)棧公眾號