Cómo convertir una cadena JSON a un mapa con Jackson JSON


Estoy tratando de hacer algo como esto pero no funciona:

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

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

Pero el IDE dice:

Asignación no controlada Map to Map<String,String>

¿Cuál es la manera correcta de hacer esto? Solo estoy usando Jackson porque eso es lo que ya está disponible en el proyecto, ¿hay una forma nativa de Java de convertir a/desde JSON?

En PHP simplemente json_decode($str) y obtendría una matriz. Necesito básicamente lo mismo aquí.

 142
Author: ROMANIA_engineer, 2010-03-26

9 answers

Tengo el siguiente código:

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); 
}   

Está leyendo desde un archivo, pero mapper.readValue() también aceptará un InputStream y puede obtener un InputStream de una cadena usando lo siguiente:

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

Hay un poco más de explicación sobre el mapeador en mi blog.

 246
Author: djna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-08 10:00:55

Intenta TypeFactory. Aquí está el código para Jackson 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);

Aquí está el código para una versión anterior de Jackson JSON.

Map<String, String> result = new ObjectMapper().readValue(
    data, TypeFactory.mapType(HashMap.class, String.class, String.class));
 45
Author: Ning Sun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-03 00:29:57

La advertencia que obtienes se hace por compilador, no por biblioteca (o método de utilidad).

La forma más sencilla de usar Jackson directamente sería:

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);

El método de utilidad al que llamas probablemente hace algo similar a esto.

 20
Author: StaxMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-27 06:17:09
ObjectReader reader = new ObjectMapper().readerFor(Map.class);

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

Tenga en cuenta que la instancia reader es segura para Subprocesos.

 17
Author: dpetruha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 05:00:28

Conversión de Cadena a mapa JSON:

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

ObjectMapper mapper = new ObjectMapper();

map = mapper.readValue(string, HashMap.class);
 9
Author: Raja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-28 17:26:25
JavaType javaType = objectMapper.getTypeFactory().constructParameterizedType(Map.class, Key.class, Value.class);
Map<Key, Value> map=objectMapper.readValue(jsonStr, javaType);

Creo que esto resolverá tu problema.

 5
Author: JackieZhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-10 06:10:59

Las siguientes obras para mí:

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

Donde getJsonAsMap se define así:

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);
    }
}

Tenga en cuenta que este fallará si tiene objetos secundarios en su json (porque no son un String, son otro HashMap), pero funcionará si su json es una lista de propiedades de valor clave como esta:

{
    "client_id": "my super id",
    "exp": 1481918304,
    "iat": "1450382274",
    "url": "http://www.example.com"
}
 3
Author: Brad Parks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-22 13:57:41

Usando el Gson de Google

¿Por qué no usar el Gson de Google como se menciona en aquí?

Muy directo e hizo el trabajo por mí:

HashMap<String,String> map = new Gson().fromJson( yourJsonString, new TypeToken<HashMap<String, String>>(){}.getType());
 3
Author: Loukan ElKadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-20 07:30:53

Aquí está la solución genérica a este problema.

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);
    }
  }

Espero que algún día alguien piense en crear un método util para convertir a cualquier tipo de Clave/valor de Mapa de ahí esta respuesta:)

 1
Author: NameNotFoundException,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-04 11:09:17