Parsing JSON in Java Play - java

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.

Related

parse strange Json response to a list

I want to parse this object to a list of string. I do not need the key but just want the value as a list of string.
I cannot have a simple model classes because the keys object are more than 1000 in some responses and are random.
So please any idea how to parse it to list in kotlin or java?
{
"data": {
"21": "593754434425",
"22": "4560864343802",
"23": "7557134347529",
"24": "5937544344255",
"25": "45608643438024",
"26": "75571343475293"
}
}
You could first deserialize it as it is, and then convert to a list.
The JSON can be represented this way:
data class Response(val data: Map<String, String>)
You can mark this class #Serializable and use Kotlinx Serialization to deserialize it, or you can use other libraries like Moshi or Jackson (with jackson-module-kotlin).
Once it's deserialized, simply get the values of the map (it's a collection):
val response = Json.decodeFromString<Response>(yourJsonString)
// this is a Collection, not List, but it should be good enough
val stringValues = response.data.values
// if you really need a List<String>
val list = stringValues.toList()
If you want to get the values in the natural order of the keys, you can also use something like:
val values = response.data.toSortedMap(compareBy<String> { it.toInt() }).values
You can use this to parse your data:
val it: Iterator<String> = json.keys()
val arrayList = ArrayList<String>()
while (it.hasNext()) {
val key = it.next()
arrayList.add(json.get(key))
}
A better way is to change the json model, if you access it.
{
"data": [
"593754434425","4560864343802",
"7557134347529","5937544344255",
"45608643438024","75571343475293"
]
}
For this problem, its handy to use the libriary org.json.
See following code snippet:
import org.json.JSONObject;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// Defining the input
String input = "{\n" +
" \"data\": {\n" +
" \"21\": \"593754434425\",\n" +
" \"22\": \"4560864343802\",\n" +
" \"23\": \"7557134347529\",\n" +
" \"24\": \"5937544344255\",\n" +
" \"25\": \"45608643438024\",\n" +
" \"26\": \"75571343475293\"\n" +
" }\n" +
"}\n";
// Parsing it to a json object with org.json
JSONObject inputJson = new JSONObject(input);
// If inputJson does not contain the key data, we return
if(!inputJson.has("data")) return;
// Else we read this data object to a new JSONObject
JSONObject dataJson = inputJson.getJSONObject("data");
// Define an array list where all the values will be contained
ArrayList<String> values = new ArrayList<>();
// Get a key set of the dat json object. For each key we get its respective value and add it to our value array list
for (String key : dataJson.keySet()) values.add(dataJson.getString(key));
// Print all values
for (String value : values) System.out.println(value);
}
}
=>
4560864343802
7557134347529
5937544344255
45608643438024
75571343475293
593754434425
Installing org.json is the easiest with a package manager like maven or gradle.
Guys i have comeup with a similar solution for the problem here
this is my model class
data class UnVerifiedTagIds(
#SerializedName("data")
val data: Object
)
and this is how i parse the respone here
val values: ArrayList<String> = ArrayList()
val list_of_tag_ids: ArrayList<String> =response.data as ArrayList<String>
The ist one is the dataclass for the response
and the 2nd one is the ApiCallInterface m using Retrofit...
and the last one is the apicall itself
I am using Kotlin language
do class name with name like this data class Result(val data:Map<String,String>)
and using library GSON for convert string json to this model
val json = "{\n" +
" \"data\": {\n" +
" \"21\": \"593754434425\",\n" +
" \"22\": \"4560864343802\",\n" +
" \"23\": \"7557134347529\",\n" +
" \"24\": \"5937544344255\",\n" +
" \"25\": \"45608643438024\",\n" +
" \"26\": \"75571343475293\"\n" +
" }\n" +
"}"
val dat = Gson().fromJson(json,Result::class.java)
if (dat.data.isNotEmpty()){
val list= dat.data.values.toMutableList()
print(list)
}
that works fine with me

Java Extract key values from nested json

i do have following JSON and i am trying to extract objects inside result
{
"status":true,
"results":{
"type1":{
"id":"type1"
},
"type2":{
"id":"type2"
}
}
}
Desired output is
type1,type2
I am using Gson for serialization and deserialization.
These are the steps you should be doing when using gson
get keys of the json objects which are inside "results" alone
get it as json object which has keys and values
collect the entry set our of the JSON
create an iterator so that later you can extract the keys
Here is code that does the same job:
public static void main(String[] args) throws Exception {
String json = "{\r\n" +
" \"status\":true,\r\n" +
" \"results\":{\r\n" +
" \"type1\":{\r\n" +
" \"id\":\"type1\"\r\n" +
" },\r\n" +
" \"type2\":{\r\n" +
" \"id\":\"type2\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(json).getAsJsonObject();
//get keys of the json objects which are inside "results" alone
//get it as json object which has keys and values
//collect the entry set our of the JSON
//create an iterator so that later you can extract the keys
Iterator<Entry<String, JsonElement>> iterator = obj.get("results")
.getAsJsonObject()
.entrySet()
.iterator();
while(iterator.hasNext()) {
//here you will get the keys like - type1 and type2
System.out.println(iterator.next().getKey());
}
}
Code Edit: What #fluffy pointed makes complete sense. Made the change

Convert Json string into Hashmap of hashmap in java

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

Java Rest Template

ResponseEntity<BaseDto> entity = restTemplate.getForEntity("/get/code/IN", BaseDto.class);
System.out.println("entity : " + entity);
System.out.println("entity.getBody() : " + entity.getBody());
System.out.println(entity.getBody().getResponseObject());
As per above rest am getting below format:
{
systemTrack=
{
createUser=admin,
createDate=2016-03-01 18:11:17,
lastUpdatedUser=admin,
lastUpdatedDate=2016-03-01 18:11:17
},
countryCode=IN, countryName=INDIA
}
How to get the values from this format?
Maybe I was unclear with my question, but i got a solution through debug mode.
It was a format which is in Linked hash map ,so what I did was I just wrote below code for json conversion of LinkedHashMap.
LinkedHashMap m = (LinkedHashMap) object;
JSONObject jsonObject = new JSONObject(m);(package of org.json.JSONObject)
and then i assigned to custom class object using
Gson gson = new Gson();
String jsonString = jsonObject.toString();
Object obj = gson.fromJson(jsonString, type);

Take Mustache Template, pass JSON and Convert to HTML

I am using this code below to merge JSON data into a template, to get HTML:
Template:
String schema = "<h1>{{header}}</h1>"
+ "{{#bug}}{{/bug}}"
+ "{{#items}}"
+ "{{#first}}"
+ "<li><strong>{{title}}</strong>
+ </li>"
+ "{{/first}}"
+ "{{#link}}"
+ "<li><a href=\"{{url}}\">{{name}}
+ </a></li>"
+ "{{/link}}"
+ "{{/items}}"
+ "{{#empty}}"
+ "<p>The list is empty.</p>"
+ "{{/empty}}";
JSON object:
try {
String template = "{\"header\": \"Colors\", "
+ "\"items\": [ "
+ "{\"name\": \"red\", \"first\": true, \"url\": \"#Red\"}, "
+ "{\"name\": \"green\", \"link\": true, \"url\": \"#Green\"}, "
+ "{\"name\": \"blue\", \"link\": true, \"url\": \"#Blue\"}"
+ " ], \"empty\": false }";
JSONObject jsonWithArrayInIt = new JSONObject(template);
JSONArray items = jsonWithArrayInIt.getJSONArray("items");
Map<String,String> ctx = new HashMap<String,String>();
ctx.put("foo.bar", "baz");
Mustache.compiler().standardsMode(true).compile("{{foo.bar}}").execute(ctx);
System.out.println("itemised: " + items.toString());
} catch(JSONException je) {
//Error while creating JSON.
}
I pass a map of data to get Mustache to work. The method looks like this:
public static Map<String, Object> toMap(JSONObject object)
throws JSONException {
Map<String, Object> map = new HashMap();
Iterator keys = object.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
map.put(key, fromJson(object.get(key)));
}
return map;
}
I am following a Mustache Guide to get the Mustache autoformation. But I don't know how to get the result I am expecting. The output should be as follows:
<h1>Colors</h1>
<li><strong></strong></li>
<li>green</li>
<li>blue</li>
I think you need to rethink your Mustache template slightly. The jMustache library (which I assume you are using) seems to always treat {{# entities as lists and iterate their contents, regardless of the data type passed in.
Something like this should work:
<h1>{{header}}</h1>
{{#items}}
<li>
{{#url}}<a href="{{.}}">{{/url}}
{{^url}}<strong>{{/url}}
{{caption}}
{{#url}}</a>{{/url}}
{{^url}}</strong>{{/url}}
</li>
{{/items}}
{{^items}}
<p>The list is empty.</p>
{{/items}}
This will produce an HMTL anchor only if a "link" value is provided, thus avoiding the jMustache if condition issue. So the JSON model would look something like this:
{
"header": "Colors",
"items": [
{"caption": "title"},
{"caption": "red", "url": "#Red"},
{"caption": "green", "url": "#Green"},
{"caption": "blue", "url": "#Blue"}
]
}
Finally, you will need to convert your JSON to something jMustache understands. I've never seen or heard of the "HTTPFunctions" class in any library I've used, but I've done some similar mapping using Gson in the past. Note that this is a very simple implementation and you may need to extend it to fit your needs:
private Map<String, Object> getModelFromJson(JSONObject json) throws JSONException {
Map<String,Object> out = new HashMap<String,Object>();
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
if (json.get(key) instanceof JSONArray) {
// Copy an array
JSONArray arrayIn = json.getJSONArray(key);
List<Object> arrayOut = new ArrayList<Object>();
for (int i = 0; i < arrayIn.length(); i++) {
JSONObject item = (JSONObject)arrayIn.get(i);
Map<String, Object> items = getModelFromJson(item);
arrayOut.add(items);
}
out.put(key, arrayOut);
}
else {
// Copy a primitive string
out.put(key, json.getString(key));
}
}
return out;
}
This basic JUnit test demonstrates the theory: http://www.pasteshare.co.uk/p/841/
Just use
Map<String, Object> s = HTTPFunctions.toMap(new JSONObject(template));

Categories