Карта JSON в карту Java - PullRequest
       6

Карта JSON в карту Java

1 голос
/ 07 октября 2019

У меня есть следующий файл json

[{
        "en": {
            "key1": "Ap",
            "key2": "ap2"
        }
    },

    {
        "ar": {
            "key1": "Ap",
            "key2": "ap2"
        }
    }
]

Я хотел бы создать карту в Java, например, ключ - это язык (например, en или ar), а значение - объект. Примерно так.

public class Category {
    private String key1;
    private String key2;
}

    Type type = new TypeToken<Map<String, Category>>() {}.getType();
    Gson gson = new Gson();

    InputStream in = MyClass.class.getResourceAsStream("/categories.json");
    String text = IOUtils.toString(in, StandardCharsets.UTF_8);
    Map<String, Category> map = gson.fromJson(text, type);

Но когда я запускаю этот код, я получаю ошибки:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 3 path $[0]

Неправильно ли моя структура Json или есть более простой способ отобразить это?

Ответы [ 4 ]

0 голосов
/ 07 октября 2019

Ваш ввод - это массив json с двумя объектами. Однако ваша целевая переменная «тип» имеет тип Object, а не «Array of Objects». Проще говоря, Map не может хранить массив.

Позволяет использовать более простой подход к этой проблеме (не рекомендуемый подход). Если мы преобразуем карту вручную в массив карт, это будет выглядеть следующим образом:

yourJson -> [Map1(en,category1(Ap,ap2)),Map2(en,category2(Ap,ap2))]

т.е. массив Карт

Таким образом, в эквиваленте Java это становится:

Type typeOfT2 = new TypeToken<ArrayList<HashMap<String, Category>>>() {}.getType();
List<HashMap<String, Category>> list = gson.fromJson(text, typeOfT2);

Мы добиваемся того, чего хотим, но есть лучшие способы сделать это. Для этого нам нужен Джексон, а не Гсон. (Кто-то может добавить решение на основе Гсона, уверен, что существует более чистое решение, чем указано выше). Здесь мы будем использовать ObjectMapper из com.fasterxml.jackson.databind.ObjectMapper

ObjectMapper om = new ObjectMapper();
List<Map.Entry<String, Category>> listx = om.readValue(text, ArrayList.class);

Если вы напечатаете listx. Вы можете видеть это (переопределено toString() класса Category):

[{en={key1=Ap, key2=ap2}}, {ar={key1=Ap, key2=ap2}}]

listx является наиболее точным представлением вашего json, а не карты.

Теперь, если вам нужна карта, я оставлю это в качестве упражнения для вас о том, как преобразовать ваш Список Map.Entry в реализацию Map.

PS: Первый длинный ответ здесь. Извиняюсь за любые ошибки.

0 голосов
/ 07 октября 2019

Указанный выше json представляет собой набор JsonObject подобных списку или массиву, поэтому просто проанализируйте его для List из Map объектов

Type type = new TypeToken<List<Map<String, Category>>>() {}.getType();
0 голосов
/ 07 октября 2019

Ваш json - это список карт, а не только карт. Поэтому вы должны добавить его к объявленному типу.

Попробуйте это:

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Category {
    private String key1;
    private String key2;

    @Override
    public String toString() {
        return "Category{" +
                "key1='" + key1 + '\'' +
                ", key2='" + key2 + '\'' +
                '}';
    }

    public static void main(String[] args) {

        String json = "[{\n" +
                "        \"en\": {\n" +
                "            \"key1\": \"Ap\",\n" +
                "            \"key2\": \"ap2\"\n" +
                "        }\n" +
                "    },\n" +
                "\n" +
                "    {\n" +
                "        \"ar\": {\n" +
                "            \"key1\": \"Ap\",\n" +
                "            \"key2\": \"ap2\"\n" +
                "        }\n" +
                "    }\n" +
                "]";

        Type type = new TypeToken<List<Map<String, Category>>>() {}.getType();
        Gson gson = new Gson();

        List<Map<String, Category>> maps = gson.fromJson(json, type);
        System.out.println(maps);
    }
}
0 голосов
/ 07 октября 2019

попробуйте прочитать этот файл JSON

 {
  "ar": {
    "key1": "Ap",
    "key2": "ap2"
  },
  "en": {
    "key1": "Ap",
    "key2": "ap2"
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...