Java: Extract index src from multiarray - java

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"));
}
}

Related

How to add JSON values to an ArrayList in Java

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);
...

How to iterate through a Map inside another Map Java

I have a map that contains data below, and I want to process the data inside the key bookAttr
{
"form46": {
"bookId": 46,
"bookAttr": {
"title": "To Kill a Mockingbird",
"author": "Harper Lee"
}
},
"form47": {
"bookId": 66,
"bookAttr": {
"title": "1984",
"author": "George Orwell"
}
}
}
I tried to iterate on the initial map, however I am getting an error when trying to process the values that I have since Java is complaining that Object cannot be converted to HashMap
HashMap<String, Object> bookForm; // contains bookFormData
for (Object value : bookForm.values()) {
HashMap<String,Object> bookAttributes = value.get("bookAttr");
System.out.println(bookAttributes);
//iterate over bookAttributes and do something else
}
How can iterate over bookAttr to be able to process its contents?
Contents of bookForm:
bookForm.entrySet().stream().forEach(e
-> System.out.println(e.getKey() + "=" + e.getValue())
);
Output:
form46={bookAttr={title=To Kill a Mockingbird, author=Harper Lee}, bookId=46}
form47={bookId=66, bookAttr={title=1984, author=George Orwell}}
Seems like the problem is that you are trying to set the Object value to variable of HashMap type. And, also try using Map instead of HashMap.
Try to replace
HashMap<String,Object> bookAttributes = value.get("bookAttr");
with
Map<String,Object> bookAttributes = (Map<String, Object>)value.get("bookAttr");

Remove the key-value pairs (nested at any level) from a Json String using LinkedTreeMap

I have a Json String representing a object which further has another nested objects. Also, I have a list of keys which I need to remove from this Json String. These keys can be at any nested level of object inside this string. Finally I need to compare this edited Json string to another string and output the differences. I need to remove those key-value pairs from first Json string because I need to ignore those keys during comparison. Currently, I am converting the Json String to LinkedTreeMap provided by Gson API and then doing Map.difference() to compare. Please suggest a solution to this.
I did it by traversing recursively inside the Nested LinkedTreeMap till I find the field and remove it if it exists. The full path of Key needs to be provide to get the exact key-value location inside the Object (like "objects.desc" in the below Json Sample to remove desc from the Json String)
Json Sample:
{
"message": "MSG",
"code": "COD001",
"objects": [
{
"resource": "Student",
"field": "StudentId",
"desc": "Student Description"
}
]
}
Code Sample:
public MapDifference<String, Object> getMapDifference(String jsonString1, String jsonString2) {
MapDifference<String, Object> mapDifference = null;
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> firstMap = gson.fromJson(jsonString1, mapType);
Map<String, Object> secondMap = gson.fromJson(jsonString2, mapType);
firstMap = CollectionUtils.isEmpty(firstMap) ? new HashMap<>() : firstMap;
secondMap = CollectionUtils.isEmpty(secondMap) ? new HashMap<>() : secondMap;
//This contains the List of keys that is required to be filtered out from Json Strings before comparision like {"message", "objects.desc"}
List<String> firstIgnoreList = getIgnoreList1();
List<String> secondIgnoreList = getIgnoreList2();
filterKeys(firstMap, firstIgnoreList);
filterKeys(secondMap, secondIgnoreList);
mapDifference = Maps.difference(firstMap, secondMap);
return mapDifference;
}
private void filterKeys(Map<String, Object> keyMap, List<String> ignoreList) {
if (!(CollectionUtils.isEmpty(keyMap) || CollectionUtils.isEmpty(ignoreList))) {
ignoreList.stream().parallel().forEach(key -> recursiveRemove(keyMap, key));
}
}
private static void recursiveRemove(Map<String, Object> keyMap, String key) {
List<String> path = Arrays.asList(StringUtils.split(key.trim(), "."));
int size = path.size();
int index = 0;
List<LinkedTreeMap> treeMapList = new ArrayList<LinkedTreeMap>();
treeMapList.add((LinkedTreeMap) keyMap);
while (index != size - 1) {
int i = index++;
List<LinkedTreeMap> treeMapListTemp = new ArrayList<LinkedTreeMap>();
treeMapList.stream().parallel().forEach(treeMap -> {
Object obj = treeMap.get(path.get(i));
if (obj instanceof List) {
treeMapListTemp.addAll((List<LinkedTreeMap>) obj);
} else if (obj instanceof LinkedTreeMap) {
treeMapListTemp.add((LinkedTreeMap) obj);
}
});
treeMapList = treeMapListTemp;
}
treeMapList.stream().parallel().forEach(treeMap -> treeMap.remove(path.get(size - 1)));
}

How to remove property fields that ObjectMapper inserts into my JSON Output?

I'm trying to create complex JSon output file with some data(HashTable collections in one big) and got some error on serializing the output. After some investigation found that need to set Visibility to these property fields and now i see strange values for HastTable in my output, that actually i don't need them. Here is some code:
PrintWriter out = null;
Map<String, String> hm = new HashMap<String, String>();
Map<String, String> hmReqMap = new HashMap<String, String>();
Map<String, String> hmResMap = new HashMap<String, String>();
Map<String, String> hmGate = new HashMap<String, String>();
Map<String, String> hmResult = new HashMap<String, String>();
JSONArray ja = new JSONArray();
JSONObject mainObj = new JSONObject();
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
try {
File file = new File(outputDirectory + File.separator + "aaa" + IConst.JSON_EXTENSION);
out = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
if (tcStats != null) {
for (SingleTest singleTest : tcStats.getTestsList()) {
Map<String, String> reqMap = new HashMap<String, String>();
Map<String, String> resMap = new HashMap<String, String>();
SomeClassAllDetails allDdetails = singleTest.getSiteTransaction();
for (Entry<String, String> entry : allDetails.getEPowerEntries().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (key.startsWith("req.")) {
reqMap.put(key.substring(4), value);
} else if (key.startsWith("res.")) {
resMap.put(key.substring(4), value);
}
}
hmGate.put("Gate", singleTest.getGate().toString());
hmReqMap.put("Request", reqMap.toString().substring(1, reqMap.toString().length() - 1));
hmResMap.put("Response", resMap.toString().substring(1, resMap.toString().length() - 1));
hmResult.put("Result", singleTest.getComparisonResult().toString());
hm.putAll(hmGate);
hm.putAll(hmReqMap);
hm.putAll(hmResMap);
hm.putAll(hmResult);
ja.put(hm);
mainObj.put(singleTest.getLabel(), ja);
}
String mapAsJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mainObj);
out.println(mapAsJson);
out.println(",");
} else if ("opening".equals(type)) {
out.println("{");
} else if ("closing".equals(type)) {
out.println("}");
}
That's the actually output and as you can see the keys like map,myArrayList are added here:
{
"map" : {
"Tran_ID" : {
"myArrayList" : [ {
"map" : {
"Response" : "value1=333333 value2=33333, value4=5555",
"Request" : "value6=44444, value7=000000",
"Gate" : "10.0.0.1",
"Result" : "Done"
}
} ]
}
}
}
How do i remove them?
If i remove the following code
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
then i got error that i need to disable SerializationFeature.FAIL_ON_EMPTY_BEANS
My goal is to create this Json Output:
{
"Tran_ID" : [{
"Response" : "value1=333333 value2=33333, value4=5555",
"Request" : "value6=44444, value7=000000",
"Gate" : "10.0.0.1",
"Result" : "Done"
}]
}
OK, here is a solution:
Go to http://www.jsonschema2pojo.org/ (NB: I'm not affiliated with this site, it's just a handy tool)
Select "Source type": "JSON" and you correct jackson version below. Also uncheck "Allow additional properties" (on the the right)
Copy/paste your wanted JSON on the left big text box.
Clic on preview at the bottom, this will generates your java classes.
Next step is to "fill" a class instance with your data
Sample "filling" code (with generated classes name):
TranID tranId = new TranID(); // {}
tranId.setResponse("value1=333333, value2=33333, value4=5555"); // { "Response": ... }
tranId.setRequest("value6=44444, value7=000000"); // { "Response": ..., "Request": ... }
tranId.setGate("10.0.0.1"); // etc
tranId.setResult("Done")
Example example = new Example(); // { "tranID": undefined }
example.setTranId(new ArrayList<>()); // { "tranID": [] }
example.getTranId().add(tranId); // { "tranID": [{ "Response": ..., "Request": ... }] }
// output
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(example);
Thanks for your help, but it didn't really help to problem
and I rewrote the code and put this one:
String jo = Json.createObjectBuilder()
.add(singleTest.getLabel(), Json.createObjectBuilder()
.add("Request", reqMap.toString().substring(1, reqMap.toString().length() - 1))
.add("Response", resMap.toString().substring(1, resMap.toString().length() - 1))
.add("Result", singleTest.getComparisonResult().toString())
.add("Gate", singleTest.getGate().toString()))
.build().toString();
You should also add to pom.xml these dependencies:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
And then you can do whatever you want with you string.
Thanks

Extracting an array from a JSON object

I have a JSON Object of the following and I need to parse the path strings inside the web array into an new JSON array.
"taxonomy": {
"source": {
"master": {
"_id": "5000",
"path": "/Appliances/Refrigerators/French Door Bottom Freezers"
},
"web": [
{
"_id": "6686",
"path": "/Appliances/Refrigerators/French Door Bottom Freezers"
},
{
"_id": "7686",
"path": "/Appliances/Refrigerators/Bottom Freezers"
}
],
},
},
I have written till this but I'm not sure how to get all the path inside the web array.
JSONObject jsonTaxonomy= _blob.optJSONObject("taxonomy");
if(jsonTaxonomy!=null)
{
if(!jsonTaxonomy.isNull("source"))
{
JSONObject jsonTaxonomySource= jsonTaxonomy.optJSONObject("source");
if(!jsonTaxonomySource.isNull("web"))
{
JSONArray jsonTaxonomySourceWeb= jsonTaxonomySource.optJSONArray("web");
if(jsonTaxonomySourceWeb!=null && jsonTaxonomySourceWeb.length()>0)
{
//Got inside the array
}
}
}
}
Without providing you with a full answer, I'm convinced you'll be able to find your answer by debugging this method and stopping it at the most inner if(). You'll be able to of what jsonTaxonomySearsWeb consists and thus how to get its values.
Modify your code to something like this:-
JSONObject jsonTaxonomy= _blob.optJSONObject("taxonomy");
if(jsonTaxonomy!=null)
{
JSONObject jsonTaxonomySource = jsonTaxonomy.optJSONObject("source");
if(jsonTaxonomySource!=null)
{
JSONArray jsonTaxonomySearsWeb= jsonTaxonomySource.optJSONArray("web");
if(jsonTaxonomySearsWeb!=null)
{
// Traverse through your JSONArray and get each Object & extract path from it.
}
}
}
I am bit unclear about the question. But As per my understanding you want to parse the JSON if you want to do that in java then you can use GSON jar from google...you can also check simple example here Gson handle object or array
Try like this...
groups = json.getJSONArray(TAG_GROUP);
System.out.println("Result Success+++"+groups);
for (int i = 0; i < groups.length(); i++) {
JSONObject c = groups.getJSONObject(i);
String source = c.getString(TAG_SOURCE);
System.out.println("Checking ::"+source);
String lname = c.getString(TAG_PATH);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_SOURCE, source);
map.put(TAG_PATH,path);
weblist.add(map); //weblist is your arraylist for both values
webpathlist.add(path); //webpathlist is your arraylist for path
}
List<String> newList = new ArrayList<String>();
newList.addAll(weblist);

Categories

Resources