I parse a JSON string.
How can I get the value of an object without the quotes? I get it with lists but it is not working with objects.
import javax.json.*;
import javax.json.stream.*;
...
String s="{ \"foo\" : [ \"abc\", \"def\" ], \"bar\" : { \"k1\" : \"v1\", \"k2\" : \"v2\" } }";
JsonReader jr = Json.createReader(new StringReader (s));
JsonObject jo = jr.readObject();
JsonArray foo = jo.getJsonArray ("foo");
for (int i = 0; i < foo.size (); i ++)
{
System.out.println (i + ": " + foo.getString (i)); // ok, no quotes
}
JsonObject bar = jo.getJsonObject ("bar");
for (Map.Entry <String, JsonValue> e : bar.entrySet ())
{
System.out.println (e.getKey() + ": " + e.getValue ().toString());
}
Thats the output.
0: abc
1: def
k1: "v1"
k2: "v2"
How can I get v1 and v2 without quotes out of the parser?
You know your input value are String, so you can do this:
for (Map.Entry <String, JsonValue> e : bar.entrySet ()) {
System.out.println (e.getKey() + ": " + ((JsonString)e.getValue ()).getString());
}
Related
I have a deep nested JsonObject like this, what is the best way to search for a specific value (null in this example) in this object?
{
"monitors" : ["monitor1"],
"index" : [{
"patterns" : [ "*" ],
"masked" : [ "abcd", "*ip_dest*::/[0-9]{1,3}$/::XXX"],
"allowed" : [ "123", null ]
}],
"permissions" : [ ]
}
For this example, I have a list of keys, I want to get the values for those keys, check if the value has Array type and if yes, search if there is any null in that array. Here is the code I have:
for (Entry<String, DataType> allowedKey : allowedKeys.entrySet()) {
DataType dataType = allowedKey.getValue();
JsonNode value = contentAsNode.get(allowedKey.getKey());
if (dataType == DataType.ARRAY && value != null) {
try {
List contentArray = DefaultObjectMapper.objectMapper.convertValue(value, java.util.List.class);
if (contentArray.contains(null)) {
this.errorType = ErrorType.NULL_ARRAY_ELEMENT;
return false;
}
} catch (Exception e) {
this.errorType = ErrorType.BODY_NOT_PARSEABLE;
return false;
}
}
}
However contains() can not find null in this case, because I have a nested array. Since the structure of the Json object could be different each time (it could have nested array or maps or just an array), I was wondering what is the best way to parse a deep nested JsonObject to find a specific value?
More clarification: in the above example Json, the key that I am interested in is index, the value of this key, is a map (but it could be an array or nested array as well, we do not know beforehand), I want to check if there is any null in index values(which in this case, there is a null)
One viable easy solution using JSONPath
public static void main(String[] args) {
String json = "{\r\n" +
" \"monitors\" : [\"monitor1\"],\r\n" +
" \"index\" : [{\r\n" +
" \"patterns\" : [ \"*\" ],\r\n" +
" \"masked\" : [ \"abcd\", \"*ip_dest*::/[0-9]{1,3}$/::XXX\"],\r\n" +
" \"allowed\" : [ \"123\", null ]\r\n" +
" }],\r\n" +
" \"permissions\" : [ ]\r\n" +
"}" ;
String path = "$.index[?(null in #.allowed)]"; //Check if allowed List has null value i.e. index->allowed
DocumentContext jsonContext = JsonPath.parse(json);
List<?> list = jsonContext.read(path);
if(list.isEmpty()) { //Based on empty List u can return true or false
System.out.println("Not found");
}else {
System.out.println("Found");
}
}
As per OP requirement psoting another solution iterate over JsonObject recursively
public static void main(String[] args) {
String json = "{\r\n" +
" \"monitors\" : [\"monitor1\"],\r\n" +
" \"index\" : [{\r\n" +
" \"patterns\" : [ \"*\" ],\r\n" +
" \"masked\" : [ \"abcd\", \"*ip_dest*::/[0-9]{1,3}$/::XXX\"],\r\n" +
" \"allowed\" : [ \"123\", null ],\r\n" +
" \"country\" : \"India\"\r\n" +
" }],\r\n" +
" \"permissions\" : [ ]\r\n" +
"}" ;
try {
iterateJson(new JSONObject(json));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void iterateJson(JSONObject jsonObject) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Iterator<String> iterator = jsonObject.keys();
while(iterator.hasNext()) {
String key = iterator.next();
if(jsonObject.get(key) instanceof JSONArray) {
JSONArray jsonArray = jsonObject.getJSONArray(key);
for(int i=0; i<jsonArray.length(); i++) {
if(jsonArray.get(i) instanceof JSONObject) {
iterateJson(jsonArray.getJSONObject(i));
}else if(jsonArray.get(i) instanceof String){
List<String> list = mapper.readValue(jsonArray.toString(), new TypeReference<List<String>>() {});
System.out.println(key+" :: "+list);
System.out.println("Contains null :: "+list.contains(null));
System.out.println();
break;
}
}
}else if(jsonObject.get(key) instanceof JSONObject) {
iterateJson(jsonObject.getJSONObject(key));
}
}
}
output
masked :: [abcd, *ip_dest*::/[0-9]{1,3}$/::XXX]
Contains null :: false
allowed :: [123, null]
Contains null :: true
patterns :: [*]
Contains null :: false
monitors :: [monitor1]
Contains null :: false
[
{
"orderDetails": [
{
"account_name": "akhil_kotak",
}
]
}
]
How to get the account name from this json, i tried doing this
String response = new String(responseBody);
//ON SUCCESS GETS JSON Object
JSONArray array = new JSONArray(response);
JSONObject obj =
array.getJSONObject(0).getJSONArray("orderDetails").getJSONObject(0);
txt_accountName.setText(obj.getString("account_name"));
If anyone can help, that would be awesome.
Thanks
Your JSON is invalid.
You can change to this.
[
{
"orderDetails": [
{
"account_name": "akhil_kotak"
}
]
}
]
Just change "account_name": "akhil_kotak" , to "account_name": "akhil_kotak" .
Just remove the comma in your JSON .
Try this .
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONArray orderDetails = jsonObject.getJSONArray("orderDetails");
for (int j = 0; j < orderDetails.length(); j++) {
JSONObject jsonObject2 = orderDetails.getJSONObject(j);
String account_name = jsonObject2.getString("account_name");
txt_accountName.setText(account_name);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
if you are using Jackson 2 .. below works
String jsonString = "[{\"orderDetails\": [{\"account_name\": \"akhil_kotak\",}]}]";
ObjectMapper mapper = new ObjectMapper();
JsonNode jnNode= mapper.readTree(jsonString);
Sting accName=jnNode.get("orderDetails").get("account_name").asText();
}
Your JSON is invalid. Remove comma! then:
Create a set of calsses and use Gson!
Add this line to dependencies in your build.gradle:
dependencies {
compile 'com.google.code.gson:gson:2.8.2' //add this line
}
Crate a set of classes:
class SomeListItem {
#SerializedName("orderDetails")
public List<InnerListItem> mOrderDetails;
}
class InnerListItem {
#SerializedName("account_name")
public String mAccountName;
}
And use them like this:
String jsonOutput = "[\n" +
" {\n" +
" \"orderDetails\": [\n" +
" {\n" +
" \"account_name\": \"akhil_kotak\"\n" +
" }\n" +
" ]\n" +
" }\n" +
"]";
Gson gson = new Gson();
Type listType = new TypeToken<List<SomeListItem>>(){}.getType();
List<SomeListItem> parsedJson = gson.fromJson(jsonOutput, listType);
String accountName = parsedJson.get(0).mOrderDetails.get(0).mAccountName;
try this. i am using org.json.simple library.
String str="[{\"orderDetails\": [{\"account_name\": \"akhil_kotak\",}]}]";
JSONParser parser=new JSONParser();
JSONArray array=(JSONArray) parser.parse(str);
JSONObject obj=(JSONObject) array.get(0);
JSONArray nestedArray=(JSONArray) obj.get("orderDetails");
System.out.println("output: "+nestedArray.get(0).get("account_name"));
it's working fine.
The end result of the code is to be able to parse the string array to integer array but as you can see I get an exception. I tried to split the [ and ] signs but when I call the first (0) element splited_game_result[0] of the array, it's returns nothing. What is the solution here? I tried using trim method.
String[] ca_po_pe = {"4:7","PAUSE","2:0","1:3 PINE","PAUSE","CANCEL","2:4","0:5 PINE","PAUSE","CANCEL"};
String canc_postp_pen_games = "";
boolean confirming = true;
for(String looped_games : ca_po_pe) {
if(confirming) { canc_postp_pen_games+=looped_games; confirming=false; }
else { canc_postp_pen_games+=", "+looped_games; } }
System.out.println("LOOPED FINAL RESULT GAMES TO INSERT COMMAS: " + "\n" + canc_postp_pen_games + "\n");
String[] fin_games_res = canc_postp_pen_games.split("[,]");
ArrayList<String> arraylist= new ArrayList<String>();
Collections.addAll(arraylist, fin_games_res);
for (String str: arraylist) {
}
System.out.println("ELEMENTS ADDED TO ARRAYLIST: " + arraylist + "\n");
int noItems = arraylist.size();
for (int i = 0; i < noItems; i++) {
String currItem = arraylist.get(i);
if (currItem.contains("PAUSE")) {
arraylist.add(new String("400"));
noItems++; }
if (currItem.contains("CANCEL")) {
arraylist.add(new String("300"));
noItems++; }
if (currItem.contains(" PINE")) {
arraylist.add(new String("500"));
noItems++; }
}
System.out.println("ELEMENTS BEFORE REMOVAL: " + "\n" + arraylist + "\n");
Iterator<String> iter_getting = arraylist.iterator();
while(iter_getting.hasNext()) {
if(iter_getting.next().contains("PAUSE")){
iter_getting.remove(); }}
Iterator<String> iter_getting1 = arraylist.iterator();
while(iter_getting1.hasNext()) {
if(iter_getting1.next().contains("CANCEL")){
iter_getting1.remove(); }}
Iterator<String> iter_getting2 = arraylist.iterator();
while(iter_getting2.hasNext()) {
if(iter_getting2.next().contains(" PINE")){
iter_getting2.remove(); }}
System.out.println("ELEMENTS AFTER REMOVAL: " + "\n" + arraylist);
System.out.println("ELEMENT ON INDEX 3 BEFORE CONVERTION TO ARRAY: " + "\n" + arraylist.get(3));
String convert = arraylist.toString();
System.out.println("CONVERTED STRING: " + convert);
String[]splited_game_result = convert.trim().split("[\\[:,\\]]");
System.out.println(" AFTER SPLITING TO ARRAY: " + "\n" + splited_game_result[0]);
Integer[] final_result = new Integer[splited_game_result.length];
int g = 0;
for(String fsgr : splited_game_result)
{ final_result[g] = Integer.parseInt(fsgr); g++;}
System.out.println("INTEGER ELEMENT ON INDEX 0: " + "\n" + final_result[1]);
For everybody who wonders, exception is raised in the very end of the source. It says NumberFormatException: For input string: "". See source below:
for(String fsgr : splited_game_result)
{ final_result[g] = Integer.parseInt(fsgr); g++;}
The reason is in the regular expession author used to split the array:
String[]splited_game_result = convert.trim().split("[\\[:,\\]]");
It produces the following array of strings:
["", "4", "7", " 2", "0", " 2", "4", " 400", " 500", " 400", " 300", " 500", " 400", " 300"]
Issue is that Integer.parseInt requires string that contain parsable integer
Possible workaround is to add if condition to ensure your fsgr is not an empty string and doesn't contain whitespaces:
for(String fsgr : splited_game_result) {
String fsgrTrim = fsgr.trim();
if (!fsgrTrim.isEmpty()) {
final_result[g] = Integer.parseInt(fsgrTrim);
g++;
}
}
Or to add try-catch clause:
for(String fsgr : splited_game_result) {
try {
final_result[g] = Integer.parseInt(fsgr);
g++;
} catch (Exception e) {
e.printStackTrace();
}
}
I still don't know what you're trying to do, but here is your exception. You are parsing an empty string and trying to parse a space before the number. Put comments in for your logic.
for (String fsgr : splited_game_result) {
try {
final_result[g] = Integer.parseInt(fsgr);
g++;
} catch(Exception e2) {
System.out.println("Exception = ["+ fsgr + "]");
}
}
Output (in middle of put. Use first and last printlns as location)
CONVERTED STRING: [4:7, 2:0, 2:4, 400, 500, 400, 300, 500, 400, 300]
AFTER SPLITING TO ARRAY:
Exception = []
Exception = [ 2]
Exception = [ 2]
Exception = [ 400]
Exception = [ 500]
Exception = [ 400]
Exception = [ 300]
Exception = [ 500]
Exception = [ 400]
Exception = [ 300]
INTEGER ELEMENT ON INDEX 0:
7
I am getting a JSON object which looks like:
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
{
"items": [{
"id": "1"
}]
}
}
I want to represent this as flat map, but I want to represent the array of items as a list.
My output should look like:
{
"id": "1",
"name":"Hw",
"price":"10",
"items": ["1"]
}
Can anybody suggest me how I can achieve this? I tried this approach:
How to deserialize JSON into flat, Map-like structure?
Output from the above tried link:
{
"id": "1",
"name":"Hw",
"price.value":"10",
"items[0].id": "1"
}
But it is representing the arrays values as array[0], array[1] which I don't need. I need this array as a list.
The JSON you've given is not valid. I assume it's:
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [{
"id": "1"
}]
}
There cannot be a generic solution to what you're asking. But for this particular JSON, this will do(using json-simple):
#SuppressWarnings("unchecked")
public Map<String, String> transform(String inputJSON) throws ParseException {
Map<String, String> result = new LinkedHashMap<>();
JSONObject inputJSONObj = (JSONObject) new JSONParser().parse(inputJSON);
String id = inputJSONObj.getOrDefault("id", "").toString();
String name = inputJSONObj.getOrDefault("name", "").toString();
String price = ((JSONObject) inputJSONObj.getOrDefault("price", new JSONObject())).getOrDefault("value", "")
.toString();
JSONArray itemsArray = (JSONArray) inputJSONObj.getOrDefault("items", new JSONArray());
int n = itemsArray.size();
String[] itemIDs = new String[n];
for (int i = 0; i < n; i++) {
JSONObject itemObj = (JSONObject) itemsArray.get(i);
String itemId = itemObj.getOrDefault("id", "").toString();
itemIDs[i] = itemId;
}
result.put("id", id);
result.put("name", name);
result.put("price", price);
result.put("items", Arrays.toString(itemIDs));
return result;
}
An approach for you with Gson. This do exactly what you want " represent this as flat map, but I want to represent the array of items as a list"
public class ParseJson1 {
public static void main (String[] args){
Type type = new TypeToken<HashMap<String, Object>>() {
}.getType();
Gson gson = new Gson();
String json = "{\n" +
" \"id\": \"1\",\n" +
" \"name\": \"Hw\", \n" +
" \"price\": {\n" +
" \"value\": \"10\"\n" +
" },\n" +
" \"items\": [{\n" +
" \"id\": \"1\"\n" +
" }]\n" +
" }\n";
HashMap<String, Object> map = gson.fromJson(json, type);
Object val = null;
for(String key : map.keySet()){
val = map.get(key);
if(val instanceof List){
for(Object s : (List)val){
System.out.println(key + ":" + s);
}
} else
System.out.println(key + ":" + map.get(key));
}
}
}
you have to convert your String in Map collection Map<String, String> which will help you to convert your Map Array to JSON format.
JSONObject jsonObject = new JSONObject();
Map<String, String> mapObject = new HashMap<String, String>();
mapObject.put("id", "1");
mapObject.put("name", "VBage");
mapObject.put("mobile", "654321");
jsonObject.put("myJSON", mapObject);
System.out.println(jsonObject.toString());
First, the JSON does not seems to have a correct format. Do you mean this?
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [{
"id": "1"
}]
}
In addition, since you were attaching the link of (How to deserialize JSON into flat, Map-like structure?), I assume you wants to flatten the JSON in the same manner, in which the result should be
{
id=1,
name=Hw,
price.value=10,
items[0]=1,
}
Also, if you just want the item to return a list of id (i.e. "items": ["1"]), then it is more logical to get a JSON of
{
"id": "1",
"name": "Hw",
"price": {
"value": "10"
},
"items": [ "1" ] // instead of "items": [{"id": "1"}]
}
The link that you have attached (How to deserialize JSON into flat, Map-like structure?) provides a general solution without any customization. It shouldn't know that "id" is the value you want to append on items.
Therefore, my first suggestion is to change the JSON to be "items": [ "1" ]
If for any reasons the JSON cannot be changed, then you will need to do some customization, which will be like this:
import org.codehaus.jackson.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.node.ValueNode;
import org.junit.Test;
public class Main {
String json = "{\n" +
" \"id\": \"1\",\n" +
" \"name\": \"Hw\", \n" +
" \"price\": {\n" +
" \"value\": \"10\"\n" +
" },\n" +
" \"items\": [{\n" +
" \"id\": \"1\"\n" +
" }]\n" +
" }\n";
#Test
public void testCreatingKeyValues() {
Map<String, String> map = new HashMap<String, String>();
try {
addKeys("", new ObjectMapper().readTree(json), map);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(map);
}
private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map) {
if (jsonNode.isObject()) {
ObjectNode objectNode = (ObjectNode) jsonNode;
Iterator<Map.Entry<String, JsonNode>> iter = objectNode.getFields();
String pathPrefix = currentPath.isEmpty() ? "" : currentPath + ".";
while (iter.hasNext()) {
Map.Entry<String, JsonNode> entry = iter.next();
// Customization here
if (entry.getKey().equals("items")) {
ArrayNode arrayNode = (ArrayNode) entry.getValue();
for (int i = 0; i < arrayNode.size(); i++) {
addKeys(currentPath + entry.getKey() + "[" + i + "]", arrayNode.get(i).get("id"), map);
}
} else {
addKeys(pathPrefix + entry.getKey(), entry.getValue(), map);
}
}
} else if (jsonNode.isArray()) {
ArrayNode arrayNode = (ArrayNode) jsonNode;
for (int i = 0; i < arrayNode.size(); i++) {
addKeys(currentPath + "[" + i + "]", arrayNode.get(i), map);
}
} else if (jsonNode.isValueNode()) {
ValueNode valueNode = (ValueNode) jsonNode;
map.put(currentPath, valueNode.asText());
}
}
}
Try understanding the format that you need, and then study the above code. It should give you the answer.
How to get these JSON values in android?
{
"one": [
{
"ID": "100",
"Name": "Hundres"
}
],
"two": [
{
"ID": "200",
"Name": "two hundred"
}
],
"success": 1
}
I tried the following but it shows that the length is 0. I can't get the array values.
JSONObject json = jParser.getJSONFromUrl(url_new);
try {
getcast = json.getJSONArray("one");
int length = getcast.length();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can use following line in your code
String str = jParser.getJSONFromUrl(url).tostring();
Following is the Code Snippet which worked for me
String str = "{"
+ "\"one\": ["
+ "{"
+ "\"ID\": \"100\","
+ "\"Name\": \"Hundres\""
+ "}"
+ "],"
+ "\"two\": ["
+ " {"
+ " \"ID\": \"200\","
+ " \"Name\": \"two hundred\""
+ " }"
+ "],"
+ "\"success\": 1"
+ "}";
try {
JSONObject obj = new JSONObject(str);
JSONArray arr = obj.getJSONArray("one");
int n = arr.length();
String id;
String name;
for (int i = 0; i < n; ++i) {
JSONObject person = arr.getJSONObject(i);
id = person.getString("ID");
name = person.getString("Name");
}
arr = obj.getJSONArray("two");
n = arr.length();
for (int i = 0; i < n; ++i) {
JSONObject person = arr.getJSONObject(i);
id = person.getString("ID");
name = person.getString("Name");
}
int success = obj.getInt("success");
}
catch(Exception ex) {
System.out.println(ex);
}
I guess the failure lies in the first line. What kind of value is url_new?
If you could get the Json from above in form of a String I'd recommend constructing the JSONObject json from the constructor JSONObject(String source) like here:
JSONObject json = new JSONObject(json_string);
That's how I use to extract the JSON from API-calls.
Reference: http://www.json.org/javadoc/org/json/JSONObject.html
You can see all constructors here.