I am new to json processing, below is the json string our clients send us, I want to
read this json string into a hashmap of hasmap so that even for the "Client"/"params" key below
I can access its key and value set and process them .
var incomingMessage =
"{
\"dev1\":\"NULL\",
\"devkp2\":\"val\",
\"compression\":\"NULL\",
\"subcode\":\"P_CODE\",
\"code\":\"PEB_USER\",
\"Client\":{
\"first_name\":\"Perf FN 422677\",
\"client_last_name\":\"DP_PSL\",
\"clientid\":\"780A832\",
\"email\":\"DP_PS#airb.com\"
},
\"clientsrc\":\"dev.client.notvalid\",
\"params\":{
\"Name\":\"ABC_PR\",
\"client_ID\":\"PSL\",
\"domain\":\"airb.com\"
}
}"
This is my current code which works fine for non-nested json strings (that is without the Client.params key in above json string):
public static void convertJsonStringToMap(String incomingMessage) {
HashMap<Object, Object> map = new HashMap<Object, Object>();
JSONObject jObject = new JSONObject(incomingMessage);
Iterator<?> keys = jObject.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
String value = jObject.getString(key);
map.put(key, value);
}
for (Map.Entry<Object, Object> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
}
I want to be able to similarly read nested keys like Client and params. I am using jdk11. I am fine with using jackson or google gson, both approaches would work.
Please help me with processing these nested json string.
A valid JSON string can be easily converted to a Map using Jackson ObjectMapper.
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> parsedMap = mapper.readValue(incomingMessage, Map.class);
It works for nested elements as well -
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String someJsonString = "{" +
"\"A\":\"1\"," +
"\"B\":2," +
"\"C\":" +
"{" +
"\"D\":\"4\"" +
"}" +
"}";
Map<String, Object> outputMap = mapper.readValue(someJsonString, Map.class);
System.out.println(outputMap);
}
Output:
{A=1, B=2, C={D=4}}
Related
I need to validate this JSON in the following method.
{
"DOG":{
"displayName":"DOGGY",
"description":"Has for legs",
"classification":"Lab"
},
"CAT":{
"displayName":"CATHY",
"description":"Has for legs",
"classification":"xxxxxx"
}
}
Now I need to validate the above json by validating each fields suchs as
displayName
description
classification
And also get key such as DOG, CAT
Now the above things should be validating.
But I am unable to get the keys such as DOG, CAT.
JSONObject jsonObject = new JSONObject(useCase.asString());
Iterator<String> keys = jsonObject.keys();
Map<String, String> myMap = new LinkedHashMap<String, String>();
Map<Object, Object> anotherMap = new LinkedHashMap<>();
while(keys.hasNext()) {
String key = keys.next();
if (jsonObject.get(key) instanceof JSONObject) {
myMap.put(((JSONObject) jsonObject.get(key)).getString("displayName")), ((JSONObject) jsonObject.get(key)).getString("classification"));
}
}
anotherMap.forEach((k, v) -> myMap.put(k.toString(), v.toString()));
myMap.forEach((k, v) -> System.out.println(k + " : " + v));*/
Goal is to validate it against json response.
I'm trying to test code that uses jackson to deserialize a string of key/value properties into a Map<String, String>. I need to find the format of the input string. I thought it was one of the following formats, but both are returning null from the objectMapper.readValue()
String testDeserStr = "{\n" +
" \"password\" : \"pwValue\",\n" +
" \"meterNumber\" : \"meterNumber1233445\",\n" +
" \"accountNumber\" : \"accountNumber6789\",\n" +
" \"key\" : \"keyValue\"\n" +
"}";
String testDeserStr = "{password=pwValue, meterNumber=meterNumber1233445, accountNumber=accountNumber6789, key=keyValue}";
With these strings, it's trying to read them via the following:
final TypeReference<HashMap<String, String>> typeRef = new TypeReference<HashMap<String, String>>() { };
Map<String, String> result = objectMapper.readValue(testDeserStr, typeRef);
I've used jackson before to both serialize and deserialize, but haven't used this TypeReference before. What am I doing wrong? What is the format of the input string?
Your 1st example is correct JSON.
Your 2nd example is incorrect JSON.
Your parsing logic is correct.
I just tested:
public class JsonTest {
public static void main(String[] args) throws IOException {
String testDeserStr = "{\n" +
" \"password\" : \"pwValue\",\n" +
" \"meterNumber\" : \"meterNumber1233445\",\n" +
" \"accountNumber\" : \"accountNumber6789\",\n" +
" \"key\" : \"keyValue\"\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
TypeReference<HashMap<String, String>> typeRef = new TypeReference<HashMap<String, String>>() {};
Map<String, String> result = objectMapper.readValue(testDeserStr, typeRef);
System.out.println(result);
}
}
and received the output:
{password=pwValue, meterNumber=meterNumber1233445, accountNumber=accountNumber6789, key=keyValue}
which is a valid result of toString() method of HashMap<String, String> base on your original input.
I am having some trouble deserializing the following JSON into a POJO. I have no control over the JSON structure, else I would've implemented it in some other way, but, that's life for you.
{
"1":{
"test":"1",
"other":"stuff"
},
"2":{
"test":"2",
"other":"stuff2"
}
}
Anyway, I am trying to deserialize by using a POJO with:
public Map<Integer, Payload> payload;
but although the Map does have a size of 2, when I try to get each of it, it's contents are null. Any idea on what I am doing wrong?
Thank you
I have no idea how the payload class looks like, but it should be something like this:
class Payload {
String test;
String other;
#Override
public String toString() {
return "Payload [test=" + test + ", other=" + other + "]";
}
}
If you assert this condition, then you can deserialize the json using a TypeToken> as token as danypata suggest... like:
public static void main(String args[]) throws InterruptedException {
String ff = "{\"1\":{" + "\"test\":\"1\"," + "\"other\":\"stuff\"" + "}," + "\"2\":{" + "\"test\":\"2\","
+ "\"other\":\"stuff2\"" + "}}";
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, Payload>>() {
}.getType();
Map<String, Payload> map = gson.fromJson(ff, mapType);
System.out.println(map);
for (Entry<String, Payload> entry : map.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
giving as result:
{1=Payload [test=1, other=stuff], 2=Payload [test=2, other=stuff2]}
1
Payload [test=1, other=stuff]
2
Payload [test=2, other=stuff2]
Why don't you use the Android JSONObject class? Then you can parse with it your entire JSON string and then you can obtain the values easily. For example this is to get the values of your "1" JSON object:
final JSONObject jsonObject = new JSONObject(jsonString);
final String test = jsonObject.getJSONObject("1").getString("test");
final String other = jsonObject.getJSONObject("1").getString("other");
How do I convert some JSON to a POJO when I don't know the name of a key?
This is my POJO:
public class Summoner {
private Details summonerDetails;
public Details getSummonerDetails() {
return summonerDetails;
}
public void setSummonerDetails(Details summonerDetails) {
this.summonerDetails = summonerDetails;
}
}
The Details class have variables like id, name, etc. -> No issues here
This is the line in my Main class where I try to map the JSON to a POJO:
Summoner test = new ObjectMapper().readValue(json, Summoner.class);
this is a JSON response example I receive:
{
"randomName":{
"id":22600348,
"name":"Ateuzz",
"profileIconId":546,
"summonerLevel":30,
"revisionDate":1378316614000
}
}
if my POJO Details member variable name is "randomName", above code will work. but when I get a response with a different name than "randomName", it doesn't. How do I make my code work for random names?
I'm using Jackson
I'm sorry I can't make a little more clear my issue.
I have solution using not only jackson API but with the use of org.json API also.
String str = "{\"randomName\":{\"id\":22600348,\"name\":\"Ateuzz\",\"profileIconId\":546,\"summonerLevel\":30,\"revisionDate\":1378316614000}}";
JSONObject json = new JSONObject(str);
Iterator<?> keys = json.keys();
while(keys.hasNext())
{
String key = (String)keys.next();
Details test = new ObjectMapper().readValue(json.getJSONObject(key).toString(), Details.class);
}
Here i have use another JAVA Json API to convert your string into jsonObject and than iterate it to get your first key value and map that to your class Details.
I assume that your json format is same as you have mention in your question.
May this will help you.
Using Jackson:
String json = "{\"randomName\":{\"id\":22600348,\"name\":\"Ateuzz\",\"profileIconId\":546,\"summonerLevel\":30,\"revisionDate\":1378316614000}}";
try
{
#SuppressWarnings("unchecked")
Map<String, Map<String, Object>> map = (Map) new ObjectMapper().readValue(json, Map.class);
for(String key : map.keySet())
{
Map<String, Object> submap = map.get(key);
System.out.println(key + ":");
for(String k : submap.keySet())
{
System.out.println("\t" + k + ": " + submap.get(k));
}
}
}
catch(IOException e)
{
e.printStackTrace();
}
I have a simple JSON object I wish to parse in Play, I am currently trying the following but having no luck:
HashMap<String,Object> result = new ObjectMapper().readValue(stringBuilder.toString(), HashMap.class);
My JSON Object looks like the following:
[{"id":"537b4f2e30047c51863094dd","from":"jacob","to":"duncan","subject":"Welcome to the message system!","message":"Hello World"},{"id":"537bb23930044f26cfd24464","from":"jacob","to":"duncan","subject":"Welcome to the message system!","message":"Hello World"}]
Can anybody provide an example on how to parse and iterate over this?
Play 2 uses Jackson API for JSON, so you should use it
Sample:
String jsonString = "[{\"id\":\"537b4f2e30047c51863094dd\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"},{\"id\":\"537bb23930044f26cfd24464\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"}]";
JsonNode node = Json.parse(jsonString);
if (node.isArray()) {
Iterator<JsonNode> elements = node.elements();
while (elements.hasNext()) {
JsonNode obj = elements.next();
debug(
"Message with ID: " + obj.get("id")
+ " from: " + obj.get("from")
+ " to: " + obj.get("to")
+ " subject: " + obj.get("subject")
+ " message: " + obj.get("message")
);
}
}
Tip: It was refactored some time ago, so depending on used Play version check Codehaus Jackson or FasterXML Jackson APIs
It looks like you've got a list, where each entry is a map key value pairs.
You can use a standard json parser to convert it into an object like this:
String json = "[{\"id\":\"537b4f2e30047c51863094dd\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"},{\"id\":\"537bb23930044f26cfd24464\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"}]";
Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
List<Map<String, Object>> data = new Gson().fromJson(json, listType);
Then you can iterate over the List and each Map as normal:
for (Map<String, Object> map : data) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
// do stuff
}
}
P.S.
It looks like all your value data is also in String form, so you might want to consider making a Map<String, String> instead of Map<String, Object> if that's actually the case.