【问题标题】:How to make nested JSON response from a single table如何从单个表中进行嵌套 JSON 响应
【发布时间】:2021-09-06 13:05:06
【问题描述】:

我有一张表,其中包含省、地区和地区内的价值

数据

+------+--------+---------------------+------------+
| ID   |Province| District            | Codes      |
+------+--------+---------------------+------------+
| 1001 | Texas  | 1st                 | 1054       |
| 1002 | Texas  | 2nd                 | 1055       |
| 1003 | Ohio   | 1st                 | 3045       |
| 1004 | Ohio   | 2nd                 | 3046       |
| 1005 | Utah   | 1st                 | 1023       |
| 1006 | Utah   | 2nd                 | 1024       |
| 1007 | Utah   | 3rd                 | 1025       |
+------+--------+---------------------+------------+

我想在用户到达终点时提供响应

{
  "country": "USA",
  "listing": {
    "Texas": {
      "1st": {
        "1054": "",
        "1055": "",
      },
      "2nd": {
        "1056": "",
        "1057": "",
      },
    },
    "Ohio": {
      "1st": {
        "3045": "",
        "3128": "",
      },
      "2nd": {
        "3046": ""
      },
    },
    "Utah": {
      "1st": {
        "1023": "",
      },
      "2nd": {
        "1024": ""
      },
      "3rd": {
        "1025": ""
      },
    },
  }
}

我选择了一个 Map 对象来生成最终结果。

@RequestMapping(path = "/getData/country", method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> retrieveData() {
    Iterable<CountryModel> stud = myDataRepo.findAll();

    Map<String, Object> parent = new HashMap<>();
    parent.put("country", "USA");

    stud.forEach(d -> {
        String r = d.getYPROVINCEN();

        Map<String, String> child = new HashMap<>();
        child.put("name", d.getYDISTRICTN());

        if (parent.containsKey(r)) {
            List<Map<String, String>> children =
                    (List<Map<String, String>>) parent.get(r);
            children.add(child);
        } else {
            List<Map<String, String>> children = new ArrayList<>();
            children.add(child);
            parent.put(r, children);
        }
    });

    return ResponseEntity.ok().body(parent);
}

我的模特

@Entity
@Table(name = "Country")
public class CountryModel {
    private String Province;
    private String District;
    private String Codes;
    //getters and setters

我的仓库

@Repository
public interface MyDataRepo extends CrudRepository<CountryModel, String> {
}

从我上面的代码中,我只成功了一步并提取了省和地区

{
  "country": "USA",
  "Texas": [
    {
      "name": "1st"
    },
    {
      "name": "2nd"
    },
  ],
  "Ohio": [
    {
      "name": "1st"
    },
    {
      "name": "2nd"
    },
  ],
  "Utah": [
    {
      "name": "1st"
    },
    {
      "name": "2nd"
    },
    {
      "name": "3rd"
    },
  ],
}

如何设置我的函数生成上面嵌套的JSON并获取代码、地区和省份?

【问题讨论】:

    标签: java json spring-boot spring-data-jpa nativequery


    【解决方案1】:

    因为我无法重现数据库。我做了一些调整来回答这个问题。

    public class TestClass {
    
        public static void main(String[] args) throws Exception {
            // dummy database table
            List<CountryModel> modelTable = new ArrayList<>();
            modelTable.add(new CountryModel("1001", "Texas", "1st", "1054"));
            modelTable.add(new CountryModel("1002", "Texas", "2nd", "1055"));
            modelTable.add(new CountryModel("1003", "Ohio", "1st", "3045"));
            modelTable.add(new CountryModel("1004", "Ohio", "2nd", "3046"));
            modelTable.add(new CountryModel("1005", "Utah", "1st", "1023"));
            modelTable.add(new CountryModel("1006", "Utah", "2nd", "1024"));
            modelTable.add(new CountryModel("1007", "Utah", "3rd", "1025"));
            modelTable.add(new CountryModel("1008", "Utah", "3rd", "1026"));
            System.out.println(retrieveData(modelTable).toString());
        }
    
        private static Map<String, Object> retrieveData(List<CountryModel> modelTable) {
            Map<String, Object> parent = new HashMap<>();
            parent.put("country", "USA");
            // inserting the listings entry
            parent.put("listing", new HashMap<String, Object>());
            @SuppressWarnings("unchecked")
            final Map<String, Object> listings = (Map<String, Object>) parent.get("listing");
    
            modelTable.forEach(entry -> {
                String province = entry.getProvince();
    
                if (!listings.containsKey(province)) {
                    listings.put(province, new HashMap<String, Object>());
                }
    
                @SuppressWarnings("unchecked")
                Map<String, Object> insideProvince = (Map<String, Object>) listings.get(province);
    
                String district = entry.getDistrict();
    
                // Since Java 9
                // insideProvince.put(district, Map.of(entry.getCode(), ""));
                
                // Before Java 9
                // Map<String, String> codeMap = new HashMap<>();
                // codeMap.put(entry.getCode(), "");
                // insideProvince.put(district, codeMap);
                
                if (!insideProvince.containsKey(district)) {
                    insideProvince.put(district, new HashMap<String, Object>());
                }
    
                @SuppressWarnings("unchecked")
                Map<String, Object> insideDistrict = (Map<String, Object>) insideProvince.get(district);
                insideDistrict.put(entry.code, "");
            });
    
            return parent;
        }
    
        static class CountryModel {
            private String id;
            private String province;
            private String district;
            private String code;
    
            CountryModel(String id, String province, String district, String code) {
                this.id = id;
                this.province = province;
                this.district = district;
                this.code = code;
            }
            // getters and setters
        }
    }
    

    解决方案非常简单。 您错过的地方是您应该使用HashMaps 而不是ArrayList

    【讨论】:

    • 嗨@dodobird 我收到这个错误Cannot resolve method 'of' in 'Map' 在这一行insideProvince.put(district, Map.of(entry.getCode(), ""));
    • 对不起,我使用Java 11 来回答这个问题。 Map.of() 是在 Java 9 之后引入的。由于您使用的是Java 8,您可以使用:Map&lt;String,String&gt; codeMap = new HashMap&lt;&gt;();insideProvince.put(district, codeMap);
    • 嗨@dodobird 我似乎无法在区域内使用上面的示例提取值
    • 你是说在Map 实例被retrieveData() 返回后反序列化它吗?
    • 从这个位Map&lt;String,String&gt; codeMap = new HashMap&lt;&gt;(); insideProvince.put(district, codeMap);我可以得到省份和地区,但代码没有显示在各个地区内
    猜你喜欢
    • 2021-05-19
    • 2019-07-25
    • 2022-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多