Spring Boot 嵌套动态 json 请求映射到 pojo

Posted

技术标签:

【中文标题】Spring Boot 嵌套动态 json 请求映射到 pojo【英文标题】:Spring Boot nested dynamic json request mapping to pojo 【发布时间】:2021-12-15 10:10:37 【问题描述】:

我正在构建一个 REST API,它接受来自用户的以下 JSON 格式的输入。 specifics 是嵌套的 JSON 对象,其 键值是动态的,其关联的数据类型也是动态的。如下所示,颜色是字符串列表,ram 是整数列表,值也可以是字符串、布尔值和整数类型。如何构建 Request POJO 类以将请求 JSON 转换为 Request Object 考虑到具体的键、值及其数据类型是动态的。在下面的 JSON 中,specifics 可以有 0..n 个 key-value,其值数据类型可以是 List of String、List of Integer、String only、boolean only 或 Just Integer value。如何将我的请求映射到 Spring Boot 后端中的 POJO。

 
        name : 
            subtitle : "iPhone xr",
            title: "The new iphone"
        ,
    
        specifics: 
          
             "color" : ["red","blue","green"],
    
             "ram" :  [ 32 , 64 ],
    
             "length": 7,
    
             "model" : 10 ,
    
             "hasLight" : true 
          
        ,
    
        description: 
          short: " This is short description",
          long:  " This is long description ",
          language: "en"
        
    
    

 class Item
       private Title title;
         private Specifics specifics;  //How to make this dynamic and key-value with distinct data type
       private Description description;
   

  public class Title 
    private String subtitle;
    private String title;
  


   public class Description 
    private String shortDes;
    private String longDes;
    private String language;
  

【问题讨论】:

【参考方案1】:

我能想到的唯一可能的处理方法是将 specifics 属性设为 Map ,如下所示:

class Item 
    private Title title;
    private Map<String, Object> specifics;
    private Description description;

现在最糟糕的部分是您需要(如果您确实需要)处理数据。考虑以下示例:

public static void main(String[] args) 
    Map<String, Object> specifics = new HashMap<>();
    specifics.put("color", List.of("red","blue","green"));
    specifics.put("ram", List.of(32 , 64));
    specifics.put("length", 7);
    specifics.put("model", 10);
    specifics.put("hasLight", true);

    Item item = new Item(specifics);

    for (Object object : item.getSpecifics().values()) 
        if (object instanceof List) 
            System.out.println("::::: List :::::");
            for (Object listObject : (List) object) 
                if (String.class.isAssignableFrom(listObject.getClass())) 
                    System.out.println("String: " + object);
                
                if (Number.class.isAssignableFrom(listObject.getClass())) 
                    System.out.println("Number: " + object);
                
            
        
        if (object instanceof Number) 
            System.out.println("Number: " + object);
        
        if (object instanceof Boolean) 
            System.out.println("Boolean: " + object);
        
    


public static class Item 
    private Map<String, Object> specifics;

    public Item(Map<String, Object> specifics) 
        this.specifics = specifics;
    

    public Map<String, Object> getSpecifics() 
        return specifics;
    

正如您所见,处理每一种可能性的逻辑是丑陋的,而且只有在增加更多可能性时才会变得更丑陋。不幸的是,它周围没有。

【讨论】:

【参考方案2】:

您可以使用Map,而不是使用 POJO 类将请求 JSON 转换为请求对象。然后您必须分析Map&lt;String, Object&gt; 并根据需要转换值(Object)。

【讨论】:

如果我使用 Map 如何用不同的数据类型指定它。就像它的值可以是 List of String 、 List of Integer 或 Just String

以上是关于Spring Boot 嵌套动态 json 请求映射到 pojo的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 支持的 JSON 映射器库都有哪些? [关闭]

如何在 Spring Boot 中将嵌套的 JSON 对象映射为 SQL 表行

仅在 XML 中忽略字段,但在 Spring Boot(xml 映射器)中不忽略 json

行映射器/转换器在spring boot中将对象数组列表转换为json

JSON 返回嵌套数组而不是对象 [Spring boot + JPA + MySQL + REST]

Spring MVC 接收的 JSON 嵌套对象的 Spring Boot JACKSON 配置