如何从单个 table 进行嵌套 JSON 响应

How to make nested JSON response from a single table

我有一个 table,其中包含省份、地区和地区内的值

数据

+------+--------+---------------------+------------+
| 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> {
}

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

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

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

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

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.