How to convert a JSON string to a Map<String, String> with Jackson JSON
JavaJacksonJava Problem Overview
I'm trying to do something like this but it doesn't work:
Map<String, String> propertyMap = new HashMap<String, String>();
propertyMap = JacksonUtils.fromJSON(properties, Map.class);
But the IDE says:
> Unchecked assignment Map to Map<String,String>
What's the right way to do this? I'm only using Jackson because that's what is already available in the project, is there a native Java way of converting to/from JSON?
In PHP I would simply json_decode($str)
and I'd get back an array. I need basically the same thing here.
Java Solutions
Solution 1 - Java
[Update Sept 2020] Although my original answer here, from many years ago, seems to be helpful and is still getting upvotes, I now use the GSON library from Google, which I find to be more intuitive.
I've got the following code:
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()
will also accept an 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.
Solution 2 - Java
Try TypeFactory
. Here's the code for 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);
Here's the code for an older version of Jackson JSON.
Map<String, String> result = new ObjectMapper().readValue(
data, TypeFactory.mapType(HashMap.class, String.class, String.class));
Solution 3 - Java
Warning you get is done by compiler, not by library (or utility method).
Simplest way using Jackson directly would be:
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);
Utility method you call probably just does something similar to this.
Solution 4 - Java
ObjectReader reader = new ObjectMapper().readerFor(Map.class);
Map<String, String> map = reader.readValue("{\"foo\":\"val\"}");
Note that reader
instance is Thread Safe.
Solution 5 - Java
Converting from String to JSON Map:
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();
map = mapper.readValue(string, HashMap.class);
Solution 6 - Java
JavaType javaType = objectMapper.getTypeFactory().constructParameterizedType(Map.class, Key.class, Value.class);
Map<Key, Value> map=objectMapper.readValue(jsonStr, javaType);
i think this will solve your problem.
Solution 7 - Java
The following works for me:
Map<String, String> propertyMap = getJsonAsMap(json);
where getJsonAsMap
is defined like so:
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);
}
}
Note that this will fail if you have child objects in your json (because they're not a String
, they're another HashMap
), but will work if your json is a key value list of properties like so:
{
"client_id": "my super id",
"exp": 1481918304,
"iat": "1450382274",
"url": "http://www.example.com"
}
Solution 8 - Java
just wanted to give a Kotlin answer
val propertyMap = objectMapper.readValue<Map<String,String>>(properties, object : TypeReference<Map<String, String>>() {})
Solution 9 - Java
Using Google's Gson
Why not use Google's Gson as mentioned in here?
Very straight forward and did the job for me:
HashMap<String,String> map = new Gson().fromJson( yourJsonString, new TypeToken<HashMap<String, String>>(){}.getType());
Solution 10 - Java
Here is the generic solution to this problem.
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);
}
}
Hope someday somebody would think to create a util method to convert to any Key/value type of Map hence this answer :)
Solution 11 - Java
Sample code for Kotlin.
class HeathCheckController {
fun get(): Any {
val config = this::class.java.getResource("/git-info.yml")?.readText()
return ObjectMapper()
.readValue(config, Map::class.java)
}
}
Gradle
val jackson = "2.13.2"