Как преобразовать строку JSON в карту<String, String> с помощью Jackson JSON

Я пытаюсь сделать что-то вроде этого, но это не работает:

Map<String, String> propertyMap = new HashMap<String, String>();

propertyMap = JacksonUtils.fromJSON(properties, Map.class);

Но IDE говорит:

Непроверенное назначение Map to Map<String,String>

Какой правильный способ сделать это? Я использую только Джексона, потому что это то, что уже доступно в проекте, есть ли собственный способ преобразования Java в / из JSON?

В PHP я бы просто json_decode($str) и я бы вернул массив. Мне нужно в основном то же самое здесь.

12 ответов

Решение

У меня есть следующий код:

public void testJackson() throws IOException {  
    ObjectMapper mapper = new ObjectMapper(); 
    File from = new File("albumnList.txt"); 
    TypeReference<HashMap<String,Object>> typeRef 
            = new TypeReference<HashMap<String,Object>>() {};

    HashMap<String,Object> o = mapper.readValue(from, typeRef); 
    System.out.println("Got " + o); 
}   

It's reading from a file, but mapper.readValue() также примет InputStream and you can obtain an InputStream from a string by using the following:

new ByteArrayInputStream(astring.getBytes("UTF-8")); 

There's a bit more explanation about the mapper on my blog.

Пытаться TypeFactory, Вот код для Джексона JSON (2.8.4).

Map<String, String> result;
ObjectMapper mapper;
TypeFactory factory;
MapType type;

factory = TypeFactory.defaultInstance();
type    = factory.constructMapType(HashMap.class, String.class, String.class);
mapper  = new ObjectMapper();
result  = mapper.readValue(data, type);

Вот код для более старой версии Jackson JSON.

Map<String, String> result = new ObjectMapper().readValue(
    data, TypeFactory.mapType(HashMap.class, String.class, String.class));

Предупреждение, которое вы получаете, делается компилятором, а не библиотекой (или служебным методом).

Простейший способ использования Джексона напрямую:

HashMap<String,Object> props;

// src is a File, InputStream, String or such
props = new ObjectMapper().readValue(src, new TypeReference<HashMap<String,Object>>() {});
// or:
props = (HashMap<String,Object>) new ObjectMapper().readValue(src, HashMap.class);
// or even just:
@SuppressWarnings("unchecked") // suppresses typed/untype mismatch warnings, which is harmless
props = new ObjectMapper().readValue(src, HashMap.class);

Служебный метод, который вы вызываете, вероятно, просто делает нечто подобное.

ObjectReader reader = new ObjectMapper().readerFor(Map.class);

Map<String, String> map = reader.readValue("{\"foo\":\"val\"}");

Обратите внимание, что reader экземпляр является потокобезопасным.

Преобразование из строки в карту JSON:

Map<String,String> map = new HashMap<String,String>();

ObjectMapper mapper = new ObjectMapper();

map = mapper.readValue(string, HashMap.class);

Просто хотел дать ответ Котлина

val propertyMap = objectMapper.readValue<Map<String,String>>(properties, object : TypeReference<Map<String, String>>() {})
JavaType javaType = objectMapper.getTypeFactory().constructParameterizedType(Map.class, Key.class, Value.class);
Map<Key, Value> map=objectMapper.readValue(jsonStr, javaType);

Я думаю, что это решит вашу проблему.

Следующие работы для меня:

Map<String, String> propertyMap = getJsonAsMap(json);

где getJsonAsMap определяется так:

public HashMap<String, String> getJsonAsMap(String json)
{
    try
    {
        ObjectMapper mapper = new ObjectMapper();
        TypeReference<Map<String,String>> typeRef = new TypeReference<Map<String,String>>() {};
        HashMap<String, String> result = mapper.readValue(json, typeRef);

        return result;
    }
    catch (Exception e)
    {
        throw new RuntimeException("Couldnt parse json:" + json, e);
    }
}

Обратите внимание, что это не удастся, если у вас есть дочерние объекты в вашем JSON (потому что они не являются Stringони еще HashMap), но будет работать, если ваш json - это список ключевых значений свойств, например:

{
    "client_id": "my super id",
    "exp": 1481918304,
    "iat": "1450382274",
    "url": "http://www.example.com"
}

Использование Google Gson

Почему бы не использовать Google Gson, как упомянуто здесь?

Очень прямолинейно и сделал работу за меня:

HashMap<String,String> map = new Gson().fromJson( yourJsonString, new TypeToken<HashMap<String, String>>(){}.getType());

Вот общее решение этой проблемы.

public static <K extends Object, V extends Object> Map<K, V> getJsonAsMap(String json, K key, V value) {
    try {
      ObjectMapper mapper = new ObjectMapper();
      TypeReference<Map<K, V>> typeRef = new TypeReference<Map<K, V>>() {
      };
      return mapper.readValue(json, typeRef);
    } catch (Exception e) {
      throw new RuntimeException("Couldnt parse json:" + json, e);
    }
  }

Надеюсь, что когда-нибудь кто-нибудь подумает создать метод util для преобразования в любой тип ключа / значения Map, отсюда и этот ответ:)

Пример кода для Котлина.

      class HeathCheckController {
    fun get(): Any {
        val config = this::class.java.getResource("/git-info.yml")?.readText()
        return ObjectMapper()
            .readValue(config, Map::class.java)
    }
}

Грейдл

      val jackson = "2.13.2"

Вот общее решение этой проблемы с использованием Object Mapper.

public static <K extends Object, V extends Object> Map<K, V> getJsonAsMap(String json, K key, V value) {
    try {
      ObjectMapper mapper = new ObjectMapper();
      TypeReference<Map<K, V>> typeRef = new TypeReference<Map<K, V>>() {
      };
      return mapper.readValue(json, typeRef);
    } catch (Exception e) {
      throw new RuntimeException("Couldnt parse json:" + json, e);
    }
  }

Надеюсь, что когда-нибудь кто-нибудь подумает создать метод util для преобразования в любой тип ключа / значения Map, отсюда и этот ответ:)

Другие вопросы по тегам