I have a json response like this
{
"queryPath": "/api/",
"nId": "f084f5ad24fcfaa9e9faea0",
"statusCode": 707
"statusMessage": "Success",
"results": {
"data": [
{
"id": "10248522500798",
"capabilities": [
"men",
"women"
],
"name": "errt2"
},
{
"id": "418143778",
"capabilities": [
"dog",
"cat"
],
"name": "Livin"
}
]
}
}
Here am adding results.data to a list as follows
private List<HashMap<String, String>> episodes = new ArrayList<HashMap<String, String>>();
episodes =helper.getJSONValue(response, "results.data");
public <T>T getJSONValue(Response res, String path ){
String json = res.asString();
JsonPath jpath = new JsonPath(json);
return jpath.get(path);
}
so episodes contains all data i mean all results.data
While i debuging am getting this way
[{id=10248522500798, name=errt2, capabilities=[men, women]}, {id=418143778, name=Livin, capabilities=[dog, cat]}]
Here i have capabilities [men, women] and [dog, cat].i need to check capability contains men or dog.
How can i do that?
If i were you i haven't done this..
Use gson and map your json into a java model. It's way better. Afterwards you can access all your model parts with getters and setters.
MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
As you see it's very simple :)
But if you want to iterate a list that contains a map you can use code block below:
List<Map<String, String>> test = new ArrayList<Map<String, String>>();
for( Map<String, String> map : test ){
for( Entry<String, String> entry : map.entrySet() ){
System.out.println( entry.getKey() + " : " + entry.getValue() );
}
}
With the code above you can get all the entry's keys and values and check them.
Edit:
You have to change your List to List<Map<String,Object>> after that:
List<Map<String, Object>> test = new ArrayList<Map<String, Object>>();
for( Map<String, Object> map : test ){
for( Entry<String, Object> entry : map.entrySet() ){
if( entry.getKey().equalsIgnoreCase( "capabilities" ) ){
List<String> myCapabilities = ( List )entry.getValue();
if( myCapabilities.contains( "dog" ) && myCapabilities.contains( "cat" ) ){
// BLA BLA
}
}
}
}
It's a nasty way.. I recommend you to use gson..
Related
I have a following response from a HTTP call which looks like this...
[{"id": 1, "name" : abc, "above50" : true} , {"id": 2, "name" : "xyc", "above50" : false, "kids" : "yes"} ]
I need to iterate through this list and find if there is a key called kids and if there is the key kids, i need to store the value . How do i do it in java?
First you need to parse the json string - it's a list of objects. If you don't have classes to match those objects, by default they can be represented as Map<String, Object>. Then you need to iterate the list, and for every object in it, you have to iterate the entries in the object. If the key matches, store it.
//parse json string with whatever parser you like
List<Map<String, Object>> list = ...;
//iterate every object in the list
for (Map<String, Object> map : list) {
//iterate every entry in the object
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (entry.getKey().equals("kids")) {
//you can store the key and the value however you want/need
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-------------------------------------------
#Test
public void test04() throws IOException {
final String preString = "[{\"id\": 1, \"name\" : \"abc\", \"above50\" : true} , {\"id\": 2, \"name\" : \"xyc\", \"above50\" : false, \"kids\" : \"yes\"} ]";
final ObjectMapper objectMapper = new ObjectMapper();
final JsonNode arrayNode = objectMapper.readTree(preString);
if (arrayNode.isArray()) {
for (JsonNode it : arrayNode) {
final JsonNode kids = it.get("kids");
if (kids != null) {
//TODO: Storage this value by you want
System.out.println(kids.asText());
}
}
}
}
You can use JSONObject or JSONArray
String message = ""list" : [{"id": 1, "name" : abc, "above50" : true} , {"id": 2, "name" : "xyc", "above50" : false, "kids" : "yes"} ]";
JSONObject jsonObject = new JSONObject(message);
JSONArray array = jsonObject.getJsonArray("list");
//so now inside the jsonArray there is 2 jsonObject
//then you can parse the jsonArray and check if there is
//a jsonObject that have "kids" like jsonObject.get("kids") != null
// or jsonObject.getString("kids") != null
I have a list of java objects as below:
[
{
id: "frwfhfijvfhviufhbviufg",
country_code: "DE",
message_key: "key1",
translation: "This is the deutsch translation"
},
{
id: "dfregregtegetgetgttegt",
country_code: "GB",
message_key: "key1",
translation: "This is the uk translation"
},
{
id: "frffgfbgbgbgbgbgbgbgbg",
country_code: "DE",
message_key: "key2",
translation: "This is the again deutch translation"
}
]
How can I convert this into a Map<String, Map<String, String>> like below:
{
"DE": {
"key1": "This is the deutsch translation",
"key2": "This is the again deutch translation"
},
"GB": {
"key1": "This is the uk translation"
}
}
I am new to java and below is my code but the code is not correct:
Map<String, Translations> distinctTranslations = customTranslationsEntities
.stream().collect(Collectors.groupingBy(
CustomTranslationsEntity::getCountryCode,
Collectors.toMap(
CustomTranslationsEntity::getMessageKey,
CustomTranslationsEntity::getTranslation),
)))
where Translations is proto buffer message like below:
message Translations {
map<string, string> translations = 1;
}
Here map<string, string> translations means map like "key1", "This is the deutsch translation"...like this.
The output should be Map<String, Map<String,String>>:
Map<String, Map<String,String>>
distinctTranslations = customTranslationsEntities
.stream()
.collect(Collectors.groupingBy(CustomTranslationsEntity::getCountryCode,
Collectors.toMap(
CustomTranslationsEntity::getMessageKey,
CustomTranslationsEntity::getTranslation,
(v1,v2)->v1)));
I added a merge function, in case there are duplicate keys.
If you want to do it without using streams then
private List<MyObject> list = // Your object List
private Map<String, Map<String, String>> map = new HashMap<>();
for(MyObject object : list){
Map<String, String> localMap;
localMap = map.getOrDefault(object.country_code, new HashMap<>());
localMap.put(object.message_key, object.translation);
if(!map.containsKey(object.country_code)){
map.put(object.country_code, localMap);
}
}
I have a map that produces json like this
{
"item": {
"Đã đặt cọc": 0,
"Chờ duyệt": 0,
"Mới tạo": 0,
"Đang đặt hàng": 0,
"Đang VC TQ-VN": 0,
"Đang phát hàng": 0,
"Đã nhận được hàng": 0,
"Đã hủy": 0
},
"name": "Đơn mua hộ"
}
And I want it to be split to this
{
"item": [
{
"name": "Đã đặt cọc",
"count": "0"
},
{
"name": "Chờ duyệt",
"count": "0"
},
...
],
"name": "Đơn kí gửi"
}
I tried this code, but it didn't work
...
HashMap<String, Object> itemSell = new HashMap<>();
// Order Sell
orderSell.put("name", "Đơn mua hộ");
for (Map.Entry<String, Long> pair : reportsStaticSellEcomos.entrySet()) {
itemSell.put("name", pair.getKey());
itemSell.put("count", pair.getValue());
orderSell.put("item", itemSell);
}
summary.add(orderSell);
The code above produces this
{
"item": {
"name": "Đã hủy",
"count": 0
},
"name": "Đơn mua hộ"
}
Yes, it only shows 1 item.
Please help me to get all of them, not only 1
Your item must be a collection of itemSell not an individual element.
Try with this
// Order Sell
orderSell.put("name", "Đơn mua hộ");
List<HashMap<String, Object>> items = new ArrayList<>(reportsStaticSellEcomos.entrySet().size());
for (Map.Entry<String, Long> pair : reportsStaticSellEcomos.entrySet()) {
HashMap<String, Object> itemSell = new HashMap<>();
itemSell.put("name", pair.getKey());
itemSell.put("count", pair.getValue());
items.add(itemSell);
}
orderSell.put("item", items);
summary.add(orderSell);
Also, using a HashMap<String, Object> to represent your Item is not very efficient or easy to understand. Instead you I suggest you create a class Item where you can encapsulate those fields.
public class Item {
private final String name;
private final int count;
// constructor
// equals and hashcode
// getter, setter
}
Your loop repeatedly overwrites the "name" and "count" keys of that itemSell map. You want to use a List here.
...
// Order Sell
orderSell.put("name", "Đơn mua hộ");
List<Map<String, Object>> itemList = new ArrayList<>();
for (Map.Entry<String, Long> pair : reportsStaticSellEcomos.entrySet()) {
Map<String, Object> itemSell = new HashMap<>();
itemSell.put("name", pair.getKey());
itemSell.put("count", pair.getValue());
itemList.add(itemSell);
}
orderSell.put("item", itemList);
summary.add(orderSell);
You might also want to check out Jackson, which can automatically do this sort of thing based on a class structure.
class Order {
String name;
List<Item> items;
}
...
class Item {
String name;
Integer count;
}
...
Order order = ...;
objectMapper.writeValueAsString(order);
I have a JSON object that is dynamically defined.
{
"lvars": {
"task1": {
"assigned" : true,
"params": {//any key value maps here}, {//any key value maps}
},
"task2": {
"assigned" : false,
"params": {//any key value maps here}, {//any key value maps}
....
},
"mvars": {
"Id": {
"type": "String",
"value": ""
},
}
}
Now in java when I am deserializing it into code it becomes somewhat like this,
Map<String, Map<String, Map<String, Map<String, Map<String, Object>>>>> m = ObjectMapper
.fromJson(getValues(), new TypeReference<>() {});
In this case "lvars" and "mvars" are fixed keys and evrything else is variable. How can I avoid the nested map of maps declaration in Java.
Just do:
Map<String,Object> data = ObjectMapper.fromJson(getValues(), new TypeReference<>() {});
Map<String, Map<String, Map<String,Object>>> dynamic_map_0 = (Map<String, Map<String, Map<String, Object>>>) data.get("lvars");
Map<String, Map<String, Map<String,Object>>> dynamic_map_1 = (Map<String, Map<String, Map<String, Object>>>) data.get("mvars");
or simpler:
JSONObject obj = new JSONObject(inputAsString);
JSONObject dynamic0 = obj.getJSONObject("lvars");
JSONObject dynamic1 = obj.getJSONObject("mvars");
You can create a class called NestedMap which is a data structure that contains references to other NestedMap objects, like so:
class NestedMap<K, Object> {
Map<K, NestedMap<K>> data;
Object object; // object to resort to if reached the end of "map-chain"
...
}
This makes the nesting a bit less messy.
I have the below json sample and i would like to get the object names dynamically without passing as string.
{
"John": {
"Age": "22",
"status": "married"
},
"Ross": {
"Age": "34",
"status": "divorced"
}
}
I want to get keys John and Ross. I tried with
JSONObject parse = JSON.parseObject("");
for (Map.Entry<String, Object> entry : parse.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
but the above code gives all the keys inside. i only want the parent keys.
you can change parse.entrySet() to parse.keySet() to get the desire result.
JSONObject parse = JSON.parseObject("");
for (Map.Entry<String, Object> entry : parse.keySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
}
Assuming the use of fastjson. Use keySet instead.
JSONObject parse = JSON.parseObject("");
for (String entry : parse.keySet()) {
System.out.println(entry);
}
This will print:
John
Ross
Tested with:
String s = "{\"John\":{\"Age\":\"22\",\"status\":\"married\"},\"Ross\":{\"Age\":\"34\",\"status\":\"divorced\"}}";
JSONObject parse = JSON.parseObject(s);
for (String entry : parse.keySet()) {
System.out.println(entry);
}