【问题标题】:Json deserialization using java enums使用java枚举的Json反序列化
【发布时间】:2020-06-29 10:30:27
【问题描述】:

我正在尝试将以下 JSON 反序列化为 java 对象。

"distance":[
  {
    "weight": 60,
    "unit": "km"
  },
  {
    "weight": 100,
    "unit": "m"
  }
]

java 对象应如下所示:

[

  {
    "km": 60
  },
  {
    "m": 100
  }
]

【问题讨论】:

  • 你能告诉我们你尝试了什么吗?

标签: java json spring-boot enums deserialization


【解决方案1】:

使用JSONObject和HashMap可以解决问题

  1. 使用 JSONObject 将 json 字符串转换为 java 类对象。
  2. 在 JSONObject 中循环项目以获取距离和单位数据。
  3. 创建HashMap对象并将其放入ArrayList中。
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;

public class Main {
    public static void main(String args[]) throws JSONException {
        ArrayList<HashMap<String, Double>> result = new ArrayList<HashMap<String,Double>>();

        String jsonStr = "{\n" +
                "    \"distance\": [\n" +
                "        { \n" +
                "            \"weight\": 60, \n" +
                "            \"unit\": \"km\" \n" +
                "        }, \n" +
                "        { \n" +
                "            \"weight\": 100, \n" +
                "            \"unit\": \"m\" \n" +
                "        } \n" +
                "    ]\n" +
                "}";

        JSONObject json = new JSONObject(jsonStr);
        JSONArray distanceArray = json.getJSONArray("distance");

        for(int i = 0; i < distanceArray.length(); i++) {
            JSONObject distanceItems = distanceArray.getJSONObject(i);
            final String unit = distanceItems.getString("unit");
            final double weight = distanceItems.getDouble("weight");

            result.add(new HashMap<String, Double>() {{
                put(unit, weight);
            }});
        }

        System.out.println(result.toString()); // output [{km=60.0}, {m=100.0}]
    }
}

【讨论】:

    【解决方案2】:

    这里我发现了两个问题,一是JSON格式不正确。应该是:

    {
     "distance":[
       {
         "weight": 60,
         "unit": "km"
       },
       {
         "weight": 100,
         "unit": "m"
       }
     ]
    }
    

    [
      {
        "weight": 60,
        "unit": "km"
      },
      {
        "weight": 100,
        "unit": "m"
      }
    ]
    

    另外,你没有明确提到你的POJO。您可以通过多种方式实现此响应。为简单起见,我假设它是简单的Map

    但是,我们首先需要使这个字符串格式正确。

    String jsonStr = "\"distance\":[\n" +
                    "  {\n" +
                    "    \"weight\": 60,\n" +
                    "    \"unit\": \"km\"\n" +
                    "  },\n" +
                    "  {\n" +
                    "    \"weight\": 100,\n" +
                    "    \"unit\": \"m\"\n" +
                    "  }\n" +
                    "]";
    jsonStr = jsonStr.substring(jsonStr.indexOf(":") + 1);
    

    创建一个类:

    @Data
    public class Distance {
        private Double weight;
        private String unit;
    }
    

    这里我使用 lombok 作为 getter 和 setter。

    将 JSON 字符串解析为 list of Distance:

    ObjectMapper objectMapper = new ObjectMapper();
    List<Distance> distances = objectMapper.readValue(jsonStr, new TypeReference<List<Distance>>(){});
    

    现在您可以将此列表转换为您想要的响应。将此响应转换为Map

    Map<String, Double> response = distances.stream().collect(Collectors.toMap(Distance::getUnit, Distance::getWeight));
    

    或者,您也可以将其转换为List&lt;Pair&lt;String, Double&gt;&gt;

    List<Pair<String, Double>> response = new ArrayList<>();
    distances.forEach(distance -> {
        response.add(new Pair(distance.getUnit(), distance.getWeight()));
    });
    

    编码愉快...

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多