I have the following JSON file:
{
"meta" : {
"stock" : "AWS",
"date modified" : 90
},
"roles" : [ "Member", "Admin" ],
"name" : "John Doe",
"admin" : true,
"email" : "john.doe#example.com"
}
I wanted to both read the values of the keys and add them to an Array List.
try {
// create object mapper instance
ObjectMapper mapper = new ObjectMapper();
// convert JSON file to map
Map<?, ?> map = mapper.readValue(Paths.get("user.json").toFile(), Map.class);
ArrayList<String> data = new ArrayList<String>();
// print map entries
for (Map.Entry<?, ?> entry : map.entrySet()) {
System.out.println((entry.getClass()) + " " + entry.getValue());
data.add((String)entry.getValue()); // trying to add entry values to arraylist
}
} catch (Exception ex) {
ex.printStackTrace();
}
I'm able to print out the data type of the value along with the value itself. All the values are part of class java.util.LinkedHashMap$Entry. I'm not able to cast the values to a String to add them to an ArrayList. How should I go about doing this? Thanks
From the jackson-databind documentation you can convert your json to a Map<String, Object> map with the following line (you have boolean, list, number and string values in your json) :
Map<String, Object> map = mapper.readValue(json, Map.class);
// it prints {meta={stock=AWS, date modified=90}, roles=[Member, Admin], name=John Doe, admin=true, email=john.doe#example.com}
System.out.println(map);
If you want to save your map values string representation into an ArrayList data you can iterate over them with a loop :
List<String> data = new ArrayList<>();
for (Object value : map.values()) {
data.add(value.toString());
}
//it will print [{stock=AWS, date modified=90}, [Member, Admin], John Doe, true, john.doe#example.com]
System.out.println(data);
Your data type of entries will be like:
meta: Map<String:Object>
roles: List<String>
admin: Boolean
So you will get an exception when casting to string for each entry value.
You should handle different data type and convert it according to your request:
Object value = entry.getValue();
I highly recommend you write more few functions to check and convert map/list/primitive variables to expected data (String):
boolean isList(Object obj);
boolean isMap(Object obj);
...
public List<String> convertMap(Map<String,Object> map);
...
Related
I need to map dynamimc json nested object into hashmap I could come up with solution but I couldn't get expected output.
Here is code
HashMap<String, Object> map = new Gson().fromJson(dynamicJson, HashMap.class);
String keys = map.keySet().stream().collect(Collectors.joining(", "));
String values = map.values().stream().map(obj -> String.valueOf(obj)).collect(Collectors.joining(", "));
System.out.println("Keys: " + keys);
System.out.println("Values: " + values);
Sample Json
{
"name": "Notification 2",
"message": "Facebook",
"tags":[
{
"city" : "Matara",
"village" : "Mirissa"
}
]
}
Actual output :
name, message, tags Notification 2, Facebook, [{city=Matara,
village=Mirissa}]
Expected output
name, message, tags/city, tag/village
Notification 2, Facebook, Matara, Mirissa
In above logic you are not processing sub elements, check below code
HashMap<String, Object> map = new Gson().fromJson(dynamicJson, HashMap.class);
Map<String, String> keyValueMap = new HashMap<>();
map.forEach((key, value) -> {
if (value instanceof List) {
((List)value).stream().forEach(obj -> { // processing sub elements
if (obj instanceof Map) {
((Map)obj).forEach((k,v) -> {
keyValueMap.put(key+"/"+k, v.toString());
});
}
});
} else { // direct value, no subelement
keyValueMap.put(key, value.toString());
}
});
The above logic will work for only elements which are inside List, so you need modify above logic little more generic based on your input json structure.
Below logic is to print the data which can be optimzed , i have written below logic so that it will be easy to understand
keyValueMap.forEach((k, v) -> {
System.out.print(k+ ",");
});
System.out.println();
keyValueMap.forEach((k, v) -> {
System.out.print(v+ ",");
});
it will give out put as below
name,tags/city,message,tags/village,
Notification 2,Matara,Facebook,Mirissa,
Thanks
Prasad
So, I'm encountering this weird problem: I'm using the Woocommerce Rest API and I need to get the src from the "images"-array.
I'v already tried to save the images-array in an other array, but then I have no idea how to get the "src" from the array:
try {
ConnectionRequest r = new ConnectionRequest();
r.setPost(false);
r.setUrl("https://" + tokens.getShop_name_token() + ".ch/wp-json/wc/v3/products?consumer_key=" + tokens.getConsumer_key_token() + "&consumer_secret=" + tokens.getSecret_key_token());
NetworkManager.getInstance().addToQueueAndWait(r);
Map<String, Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
//JSON Filter
ArrayList<Map<String, String>> myList = (ArrayList<Map<String, String>>) result.get("root");
for (int i = 0; i < myList.size(); i++) {
Map<String, String> dtls = myList.get(i);
productsArr.add(dtls.get("name"));
productStock.add(dtls.get("stock_status"));
productDateCreated.add(dtls.get("date_created"));
//TODO: Filter out image-soure
productImages.add(dtls.get("images"));
}
System.out.println(productImages);
Output: [[], [], [], [{id=16.0, date_created=2018-11-08T15:21:14,
date_created_gmt=2018-11-08T15:21:14,
date_modified=2018-11-08T15:21:14,
date_modified_gmt=2018-11-08T15:21:14,
src=https://website.com/wp-content/uploads/2018/11/1.jpg, name=Vneck
Tshirt, alt=}],
[{id=15.0, date_created=2018-11-08T15:21:14, date_created_gmt=2018-11-08T15:21:14,
date_modified=2018-11-08T15:21:14,
date_modified_gmt=2018-11-08T15:21:14,
src=https://website.com/wp-content/uploads/2018/11/21.jpg,
name=Tshirt, alt=}]]
I got this far. Now my question is: How can I filter out the index to get the "src" of the image?
As you use the rather minimally-featured com.codename1.io.JSONParser JSON parser, which parses JSON to a Map<String, Object> and nothing else, then what you want to do is convert the Object that you get selecting a value to the expected type, and repeat from there.
If the top-level JSON object is an array, then a special "root" element is created, which is what you are getting here. That means that the structure of your JSON is parsed as this:
{
"root": [
{
"name": <str>,
"stock_status": <???>,
"date_created": <str>,
"images":
{
"id": <num>,
"date_*": <str>,
"src": <str>,
"name": <str>,
"alt": <str>
}
]
}
]
}
So, to extract an image's src, you have extracted the "root" array and iterated over it. Instead of casting the results to Map<String, String> however, you want to keep them as Map<String, Object>:
for (const Map<String, Object> element : (List<Map<String, Object>>) result.get("root")) {
// The "element" object has an "images" value that is a list of objects
for (const Map<String, Object> image : (List<Map<String, Object>>) element.get("images")) {
// Save the "src" field of each image
productImages.add((String) image.get("src"));
}
}
I'm trying to parse productId, name, and price from my below JSON in the REST API - but I'm getting null pointer exception when I try to get he name - String name = (String) obj.get("name");, may I know what I'm doing wrong here?
Any help would be really appreciated.
Thanks!
JSON:
{
"id": "af0b86eb-046c-4400-8bc4-0e26042b8f53",
"products": [{
"productId": "1234",
"name": "apple",
"price": "383939"
}
]
}
Controller.java
public ResponseEntity<Object> create(#RequestBody Map<String, Object> obj) {
Product response = myservice.create(obj);
return new ResponseEntity<Object>(response, HttpStatus.CREATED);
}
Service.java
public Product create(Map<String, Object> obj) {
for (Entry<String, Object> entry : obj.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
}
Object [] products = (Object[]) obj.get("products");
HashMap <String, Object> productOne = (HashMap) products[0];
String productId = (String) productOne.get("name");
System.out.println("productId: " +productId);
String name = (String) obj.get("name");
System.out.println("name: " +name);
}
Output:
Key : products Value : [{productId=1234, name=apple, price=383939}]
By obj.get("name"), you try getting value by key name from a top-level of your json request, while it's a property of a second-level object
In pseudo-code (skipping casting and null-checks) it should look like this:
obj.get("products")[0].get("name")
In Service.java you print obj inside for loop. Your print says that key is products and value is an array of objects.
So in following line obj is that top-level object and not contains “name” field.
String name = (String) obj.get("name");
System.out.println("name: " +name);
What if you call obj.get(“products”) and try to cast it into a collection? Then trying to fetch the first index from the collection. It should contain the inner object which contains name key and value.
You should reason exactly as you see the json, by depth(or level).
Initially the whole json is contained in the obj map which contains two key-value pairs:
(key = "id", value = "af0b86eb-046c-4400-8bc4-0e26042b8f53")
(key = "products", value = [{"productId": "1234", "name": "apple", "price": "383939"}])
Since you are interested in product details, the first step is two extract the array products like this:
Object [] products = obj.get("products");
Now product is an array of objects. Since you know that your objects are in turn hash maps you can cast each object to a map and access the key(s) that you want:
HashMap <String, Object> productOne = (HashMap) products[0];
String productId = (String) productOne.get("productId");
String name = (String) productOne.get("name");
..
I've got my php code:
<?php
require('conn.php');
$json = array();
$newquery = "SELECT * FROM absent";
$newresult = mysqli_query($conn, $newquery);
$jsonData = array();
while ($array = mysqli_fetch_array($newresult)) {
array_push($jsonData,array(
"username"=>$array['username'],
"date"=>$array['date']
));
}
echo json_encode(array("result"=>$jsonData), true);
mysqli_close($conn);
?>
and it returned :
{"result":[{"username":"verarmond","date":"2016-11-17"},{"username":"henk","date":"2016-11-15"}]}
How can i get only usernames and only dates in android ??
Thanks and regard.
HashMap is a data structure based on (key, value) pairs.
So, when you do this:
map.put("iOS", "100");
map.put("Android", "101");
You put the value "100" at "iOS" key, and value "101" at "Android" key.
If you want to access this values, you simply use the "map" object and get the value by the key, like this:
String val1 = map.get("iOS"); //this returns "100"
String val2 = map.get("Android"); // this returns "101"
To get all the entries from a map:
ArrayList<String> values = new ArrayList<>();
for (
Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String Value = entry.getValue();
values.add(Value); //this will add all the values in the hashmap into `values` arraylist
}
It is very easy, you can do it by translating your JSON result to a JSON object with:
JSONObject jsonResult = new JSONObject(jsonString);
Then take your JSON array named result:
JSONArray jsonResultArray = new JSONArray(jsonResult.getJSONArray("result"));
Now you can iterate through your JSON Array to get the required elements:
for(JSONObject jsonObject:jsonResultArray) {
Log.d("TAG", "User: " + jsonObject.getString("username"));
Log.d("TAG", "Date: " + jsonObject.getString("date"));
}
You should know that every { means a JSONObject and the [ means a JSONArray, wit that you should have enough to go.
I wrote the code on the fly and can't check it now, maybe there are some typo or error.
I'm using the following code to get JSON data from file, currently I was able to achieve the JSON but in one string. I want to parse it to array. The json file is like this:
{
"employee": [
{
"name": "joan",
"lastname": "test",
"age": 23
},
I'm using the following code to get the data but I get it in one string and I want to print some of the data
JSONObject jsonObject = (JSONObject) parser
.parse(new FileReader("C:\\MockData\\Json\\js.txt"));
JSONParser parser1 = new JSONParser();
ContainerFactory containerFactory = new ContainerFactory() {
public List<?> creatArrayContainer() {
return new LinkedList<Object>();
}
public Map<?, ?> createObjectContainer() {
return new LinkedHashMap<Object, Object>();
}
};
Map<?, ?> json = (Map<?, ?>) parser1.parse(jsonObject.toJSONString(), containerFactory);
Iterator<?> iter = json.entrySet().iterator();
System.out.println("==iterate result==");
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
System.out.println(entry.getKey() + "=>" + entry.getValue());
}
this is the output
employee=[{age=23, name=joan, lastname=test}, {age=22, name=Alex, lastname=avz}, {age=65, name=Dan, lastname=severn}]
Here the entry.getValue() is retuen one concatenated string of the array,
the while is running just one time...
but I want to loop on it to take the key value. How should I do that?
for example if I want to print name alex witn age 22 how should I do that?
Note: The file can be changed so I don't know the keys (now its name but in can be firstName and any other field for that i need generic solution).
if there is a way to use different parser that can do that Im open.
The following is the full solution to your question.
With this code you can break down the data to each employee and also separate the employee attributes.
Set<String> keySet = jsonObject.keySet();
Iterator keySetIterator = keySet.iterator();
while(keySetIterator.hasNext()){
JSONArray array = (JSONArray)jsonObject.get(keySetIterator.next());
while(employeeKeySetIterator.hasNext()){
String employeeKey = employeeKeySetIterator.next().toString();
System.out.println(employeeKey + " : "+ employee.get(employeeKey));
}
}
}
You need to cast the inner json string to a JSONArray
JSONArray array = (JSONArray)jsonObject.get("employee");
Iterator<JSONObject> iterator = array.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toString());
}