Reputation: 1512
The purpose of this code is to convert unknown number of parameters with unknown number of values into the Map<String, List<String>>
(key - parameter name, value - list of possible parameter values), assuming that every kind of type would parse to String.
The problem is that numbers and other formats are not parsing into String, and jsonField.getValue()
is not a value node (jsonField.getValue().isValueNode()
returns false
) so I cant use jsonField.getValue().asText()
since it returns null
.
My approach:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.map.ListOrderedMap;
public ListOrderedMap<String, ArrayList<String>> convertParamsFromJson(String jsonParams) throws IOException {
ListOrderedMap<String, ArrayList<String>> convertedParams = new ListOrderedMap<>();
Iterator<Entry<String, JsonNode>> fieldsFromJson = convertFromJson(jsonParams).fields();
ObjectMapper mapper = new ObjectMapper();
while (fieldsFromJson.hasNext()) {
Entry<String, JsonNode> jsonField = fieldsFromJson.next();
String paramName = jsonField.getKey();
String paramValue = jsonField.getValue();
if (jsonField.getValue().isArray()) {
convertedParams.put(paramName, mapper.convertValue(paramValue, ArrayList.class));
}
}
return convertedParams;
}
input:
{
"firstParam":[1],
"secondParam": ["a","b","c","d"],
"thirdParam": [1,2,3],
"fourthParam":[true,false]
}
expected output:
<[MapEntry[key="firstparam", value=["1"]],
MapEntry[key="secondparam", value=["a","b","c","d"]],
MapEntry[key="thirdparam", value=["1","2","3"]],
MapEntry[key="fourthparam", value=["true", "false"]]]>
output:
<[MapEntry[key="firstparam", value=[1]],
MapEntry[key="secondparam", value=["a", "b", "c", "d"]],
MapEntry[key="thirdparam", value=[1,2,3]],
MapEntry[key="fourthparam", value=[true, false]]]>
Upvotes: 1
Views: 795
Reputation: 38655
By default Jackson
library converts JSON
primitives to suitable types. Consider below example:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
String json = "{\"firstParam\":[1],\"secondParam\": [\"a\",\"b\",\"c\",\"d\"],\"thirdParam\": [1,2,3],\"fourthParam\":[true,false]}";
ObjectMapper mapper = new ObjectMapper();
Map<String, List<Object>> map = mapper.readValue(json, Map.class);
map.forEach((k, v) -> {
System.out.print(k + " => ");
v.forEach(i -> System.out.print(i + " (" + i.getClass().getSimpleName() + "), "));
System.out.println();
});
}
}
Above code prints:
firstParam => 1 (Integer),
secondParam => a (String), b (String), c (String), d (String),
thirdParam => 1 (Integer), 2 (Integer), 3 (Integer),
fourthParam => true (Boolean), false (Boolean),
But we can force to convert list items to String
by providing a type we need to achieve by using TypeReference
:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
String json = "{\"firstParam\":[1],\"secondParam\": [\"a\",\"b\",\"c\",\"d\"],\"thirdParam\": [1,2,3],\"fourthParam\":[true,false]}";
TypeReference<LinkedHashMap<String, List<String>>> mapOfStringListsType = new TypeReference<LinkedHashMap<String, List<String>>>() {};
ObjectMapper mapper = new ObjectMapper();
Map<String, List<String>> map = mapper.readValue(json, mapOfStringListsType);
map.forEach((k, v) -> {
System.out.print(k + " => ");
v.forEach(i -> System.out.print(i + " (" + i.getClass().getSimpleName() + "), "));
System.out.println();
});
}
}
Above code prints:
firstParam => 1 (String),
secondParam => a (String), b (String), c (String), d (String),
thirdParam => 1 (String), 2 (String), 3 (String),
fourthParam => true (String), false (String),
Upvotes: 1