Json десериализация с использованием java перечислений - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь десериализовать следующий JSON объект java.

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

Объект java должен выглядеть следующим образом:

[

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

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Эту проблему можно решить с помощью JSONObject и HashMap

  1. . Используйте JSONObject для преобразования json строки в java объект класса.
  2. L oop элементов внутри 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}]
    }
}
0 голосов
/ 19 марта 2020

Здесь я обнаружил две проблемы, во-первых, она не очень хорошо сформирована 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 для получения и установки.

Разбор JSON строки в список из 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<Pair<String, Double>>:

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

Счастливое кодирование ...

...