成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Boot 優雅處理 JSON動態屬性

開發 前端
有時我們需要處理具有未知屬性的動態 JSON 對象,這些對象的結構可能在運行時有所不同,超出了預定義數據結構的范圍。在這種情況下,我們就需要采用一些特殊的技術或策略來靈活地處理這些動態 JSON 對象。

環境:SpringBoot3.4.0

1. 簡介

使用 Jackson 處理預定義的 JSON 數據結構非常簡單。Spring Boot 默認使用 Jackson 作為其 JSON 處理庫,因此,在默認情況下,我們無需進行任何額外的配置即可輕松地在 Spring Boot 應用中序列化和反序列化 JSON 數據。

然而,有時我們需要處理具有未知屬性的動態 JSON 對象,這些對象的結構可能在運行時有所不同,超出了預定義數據結構的范圍。在這種情況下,我們就需要采用一些特殊的技術或策略來靈活地處理這些動態 JSON 對象。

1.1 什么是動態屬性?

首先,我們有如下的實體類:

public class Product {
  private String name;
  private String category;
  // getters, setters
}

對應的JSON字符串如下:

{
  "name": "SpringBoot實戰案例100例",
  "category": "book",
  "details": {
    "price": "70",
    "author": "XGPack"
  }
}

這里的 "details" 代表的是動態屬性,它在 Product 實體對象中并沒有預先定義的對應屬性。

接下來,本篇文章將介紹4種方式處理這種JSON對象中包含動態屬性的情況。

2. 實戰案例

2.1 使用JsonNode屬性

我們可以在 Product 類中添加一個類型為 com.fasterxml.jackson.databind.JsonNode 的屬性,用來接收和處理上述的 details 動態屬性,如下示例:

public class Product {


  // other properties
  private JsonNode details;
  // getters, setters
}

測試代碼

ObjectMapper objectMapper = new ObjectMapper() ;
String json = """
    {
      "name": "SpringBoot實戰案例100例",
      "category": "book",
      "details": {
        "price": "70",
        "author": "XGPack"
      }
    }
  """ ;
Product product = objectMapper.readValue(json, Product.class) ;
System.err.printf("name: %s, category: %s%n", product.getName(), product.getCategory()) ;
System.out.println("--------------------------------") ;
System.err.printf("price: %s, auther: %s%n", 
  product.getDetails().get("price").asText(),
  product.getDetails().get("author").asText()) ;

輸出結果

圖片圖片

問題得到了解決,但這個解決方案存在一個問題;由于我們有一個 JsonNode 字段,我們的類依賴于 Jackson 庫。

2.2 使用Map集合

我們還可以使用Map集合來接收這些動態屬性,如下示例:

public class Product_Map {
  // other properties
  private Map<String, Object> details;
  // getters, setters
}

測試代碼

ObjectMapper objectMapper = ... ;
String json = ... ;
Product product = objectMapper.readValue(json, Product.class) ;
System.err.printf("name: %s, category: %s%n", product.getName(), product.getCategory()) ;
System.out.println("--------------------------------") ;
System.err.printf("price: %s, author: %s%n", 
    product.getDetails().get("price"),
    product.getDetails().get("author")) ;

此種方式有通過JsonNode差不多,只是這種方式不依賴于jackson包。

2.3 使用@JsonAnySetter注解

當對象只包含動態屬性時(details),上面的2個解決方案是很好的選擇。然而,有時我們在一個 JSON 對象中混合了固定屬性和動態屬性。也就是如下數據格式時:

{
  "name": "SpringBoot實戰案例100例",
  "category": "book",
  "price": "70",
  "author": "XGPack"
}

動態屬性與固定的屬性是平級混合在一起,這種情況我們可以使用 @JsonAnySetter 注解來標記一個方法,以處理額外的、未知的屬性。這樣的方法應該接受兩個參數:屬性的key和value。

public class Product {


  // other properties
  private Map<String, Object> details = new LinkedHashMap<>() ;
  @JsonAnySetter
  public void setDetail(String key, Object value) {
      details.put(key, value) ;
  }
  // getters, setters
}

這里,我們在 setter 方法上使用 @JsonAnySetter 注解,以便該方法能夠處理那些動態的屬性。

測試代碼

ObjectMapper objectMapper = ... ;
String json = ... ;
Product product = objectMapper.readValue(json, Product.class) ;
System.err.printf("name: %s, category: %s%n", product.getName(), product.getCategory()) ;
System.out.println("--------------------------------") ;
System.err.printf("price: %s, author: %s%n", 
    product.getDetails().get("price"),
    product.getDetails().get("author")) ;

輸出結果

圖片圖片

2.4 自定義反序列化器

在大多數情況下,這些解決方案都能很好地工作;然而,當我們需要更多的控制時,我們可以使用自定義反序列化器來處理。

public class ProductDeserializer extends StdDeserializer<Product> {
  public ProductDeserializer() {
    this(null);
  }
  public ProductDeserializer(Class<?> vc) {
    super(vc);
  }
  @Override
  public Product_CustomDeserializer deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    JsonNode node = jp.getCodec().readTree(jp) ;
    // 獲取通用字段
    String name = node.get("name").asText() ;
    String category = node.get("category").asText() ;
    // 獲取動態屬性
    JsonNode detailsNode = node.get("details");
    String price = detailsNode.get("price").asText() ;
    String author = detailsNode.get("author").asText() ;
    Map<String, Object> details = new HashMap<>() ;
    details.put("price", displayAspectRatio) ;
    details.put("author", audioConnector) ;
    return new Product(name, category, details) ;
  }
}

測試代碼:

ObjectMapper objectMapper = new ObjectMapper() ;
// 注冊反序列獲器
SimpleModule module = new SimpleModule();
module.addDeserializer(Product.class, new ProductDeserializer());
objectMapper.registerModule(module) ;
String json = ... ;
// ...

這里通過編程的方式注冊自定義反序列化器,其它代碼都是一樣的。

我們還可以通過更簡單的方式進行處理,直接通過注解的方式注冊自定義的反序列化器:

@JsonDeserialize(using = ProductDeserializer.class)
public class Product {
  // ...
}

在Spring Boot環境下,那么還可以通過如下方式定義和注冊反序列化器。

@JsonComponent
public class PackJsonComponent {


  // 自定義反序列化
  public static class Deserializer extends JsonDeserializer<Product> {
    @Override
    public Product deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
      JsonNode node = jp.getCodec().readTree(jp) ;
      String name = node.get("name").asText() ;
      String category = node.get("category").asText() ;
      
      // ...
      return new Product(name, category, details) ;
    }
  }
}

使用@JsonComponent注解即可。

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2021-04-20 10:50:38

Spring Boot代碼Java

2024-09-27 12:27:31

2022-10-26 07:14:25

Spring 6Spring業務

2014-07-22 09:01:53

SwiftJSON

2024-08-02 09:15:22

Spring捕捉格式

2025-03-11 00:55:00

Spring停機安全

2020-03-16 17:20:02

異常處理Spring Boot

2025-01-13 12:46:31

SpringBootJacksonJSON

2023-04-17 23:49:09

開發代碼Java

2024-12-06 09:27:28

2024-10-16 12:23:55

技巧Spring驗證

2022-04-08 16:27:48

SpringBoot異常處理

2023-09-13 08:56:51

2021-01-07 14:06:30

Spring BootJUnit5Java

2021-03-09 13:18:53

加密解密參數

2024-10-11 11:46:40

2023-11-01 08:58:10

2022-06-04 12:25:10

解密加密過濾器

2022-05-18 12:04:19

Mybatis數據源Spring

2025-04-17 03:33:00

SpringSQL動態查詢
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线视频网址 | 久久久久国产精品 | 久久久久一区二区三区四区 | 欧美福利一区 | 福利片在线观看 | 精品久 | www.色综合 | 国产一级黄色网 | 欧美成年黄网站色视频 | 国产一区二区三区在线 | 日韩电影免费在线观看中文字幕 | 亚洲av毛片| 天天操夜夜操 | 日韩一区二区精品 | 久久免费精品视频 | a在线视频观看 | 国产伊人久久久 | 亚洲精品一区二区网址 | 亚洲天堂av在线 | 中文字幕一区二区三区精彩视频 | 日韩欧美精品 | 国产午夜精品一区二区三区 | 日韩图区 | 成人亚洲视频 | 久久免费电影 | 日本黄色免费片 | 欧美成人猛片aaaaaaa | 久久精品网 | 九九热免费观看 | 国产激情精品 | 最新91在线| 色噜噜狠狠色综合中国 | 日韩一二区在线 | 欧美精品福利视频 | 国产精品视频在线观看 | 久久免费精品 | 国产精产国品一二三产区视频 | av国产精品毛片一区二区小说 | www.男人天堂.com | 天天躁日日躁xxxxaaaa | 亚洲午夜av |