I have seen many examples, but none of them are not like what i want.
Consider I have a JSONObject like:
[ {
"id" : "572add95e4b0b04f4d502a3c",
"amount" : 109.27,
"sourceCurrency" : "MXN",
"targetCurrency" : "USD",
"recipientBankId" : "572add95e4b0b04f4d502a37",
"iban" : "5805742027",
"created" : "2016-05-05T05:43:49.194"
}, {
"id" : "572add95e4b0b04f4d502a3e",
"amount" : 722.41,
"sourceCurrency" : "GBP",
"targetCurrency" : "INR",
"recipientBankId" : "572add95e4b0b04f4d502a32",
"iban" : "4688276585",
"created" : "2016-05-05T05:43:49.2"
}]
and i want to access to the second json and iban value.
How can i do it?
With your json content
String json = "[ {\n" +
" \"id\" : \"572add95e4b0b04f4d502a3c\",\n" +
" \"amount\" : 109.27,\n" +
" \"sourceCurrency\" : \"MXN\",\n" +
" \"targetCurrency\" : \"USD\",\n" +
" \"recipientBankId\" : \"572add95e4b0b04f4d502a37\",\n" +
" \"iban\" : \"5805742027\",\n" +
" \"created\" : \"2016-05-05T05:43:49.194\"\n" +
"}, {\n" +
" \"id\" : \"572add95e4b0b04f4d502a3e\",\n" +
" \"amount\" : 722.41,\n" +
" \"sourceCurrency\" : \"GBP\",\n" +
" \"targetCurrency\" : \"INR\",\n" +
" \"recipientBankId\" : \"572add95e4b0b04f4d502a32\",\n" +
" \"iban\" : \"4688276585\",\n" +
" \"created\" : \"2016-05-05T05:43:49.2\"\n" +
"}]";
You first need to get a JSONArray from your json content :
JSONArray array = new JSONArray(json);
Then you read the second ( at the index 1 ) JSONObject within the array:
JSONObject o = array.getJSONObject(1);
And finally you read the iban from the JSONObject :
String secondIban = o.getString("iban");
System.out.println(secondIban);
With of course all this surrounded with a try/catch to catch JSONException:
try {
JSONArray array = new JSONArray(json);
JSONObject o = array.getJSONObject(1);
String secondIban = o.getString("iban");
System.out.println(secondIban);
}catch(JSONException jse){
jse.printStackTrace();
}
Note
If you want to be aware that the iban field doesn't exist use o.getString("iban").
A JSONException will be thrown if the field is missing.
If you are okay to work with an empty string "" as default value for the eventually missing field then use o.optString("iban") to read the field.
you can do something like below.
public static void main(String[] args) {
String json = "[{\n" +
" \"id\" : \"572add95e4b0b04f4d502a3c\",\n" +
" \"amount\" : 109.27,\n" +
" \"sourceCurrency\" : \"MXN\",\n" +
" \"targetCurrency\" : \"USD\",\n" +
" \"recipientBankId\" : \"572add95e4b0b04f4d502a37\",\n" +
" \"iban\" : \"5805742027\",\n" +
" \"created\" : \"2016-05-05T05:43:49.194\"\n" +
"}, {\n" +
" \"id\" : \"572add95e4b0b04f4d502a3e\",\n" +
" \"amount\" : 722.41,\n" +
" \"sourceCurrency\" : \"GBP\",\n" +
" \"targetCurrency\" : \"INR\",\n" +
" \"recipientBankId\" : \"572add95e4b0b04f4d502a32\",\n" +
" \"iban\" : \"4688276585\",\n" +
" \"created\" : \"2016-05-05T05:43:49.2\"\n" +
"}]";
JSONArray objects = new JSONArray(json);
System.out.println(((JSONObject)objects.get(1)).get("iban"));
}
Use optString instead getString.
optString - Will return blank string if element/key not found in JSON.
getString - Will throw an exception.
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
================================
public static void main(String[] args) throws JSONException {
String str = "[{\"id\":\"572add95e4b0b04f4d502a3c\",\"amount\":109.27,\"sourceCurrency\":\"MXN\",\"targetCurrency\":\"USD\",\"recipientBankId\":\"572add95e4b0b04f4d502a37\",\"iban\":\"5805742027\",\"created\":\"2016-05-05T05:43:49.194\"},{\"id\":\"572add95e4b0b04f4d502a3e\",\"amount\":722.41,\"sourceCurrency\":\"GBP\",\"targetCurrency\":\"INR\",\"recipientBankId\":\"572add95e4b0b04f4d502a32\",\"iban\":\"4688276585\",\"created\":\"2016-05-05T05:43:49.2\"}]";
JSONArray jsonArray = new JSONArray(str);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.optJSONObject(i);
/* optString - will return blank string if element not found */
String iban = jsonObject.optString("iban");
System.out.println(iban);
}
}
What you should do is transform string into json:
public JsonObject parseJsonString(String jsonString) {
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = (JsonObject) jsonParser.parse(jsonString);
return jsonObject;
}
then extract values that you are after:
final String iban = jsonObject.get("iban").getAsString();
To read a value from JSON you can only with the next methods:
Data bind
Tree Model
Streaming API
XPath like
Which method to use is up to you because all methods have advantage and disadvantage.
Engines:
Fastjson supports Data bind, XPath like
Gson supports Data bind, Tree Model, Streaming API
Jackson supports Data bind, Tree Model, Streaming API
JsonPath supports XPath like
Genson supports Data bind, Tree model with Jsonp, Streaming API
Ig json parser supports Data bind
Moshi supports Data bind
JSON java supports Tree Model
LoganSquare supports Data bind
I guess you want to select only a part from json, so xpath like could be your choice with syntax like this $[1].iban (JsonPath)
Related
I have a JSON in the following format. I want to replace the Nutrition at the last index with Title using java code.
Current Format
{
"nutrients" : [{
"Nutrient" : "Alcohol, ethyl",
"Amount" : " 3.9",
"Unit" : " g"
}, {
"Nutrient" : "Fiber",
"Amount" : " 0.0",
"Unit" : " g"
}, {
"Nutrient" : "Alcoholic beverage, BUDWEISER, regular, beer"
}]
}
Required Format
{
"nutrients" : [{
"Nutrient" : "Alcohol, ethyl",
"Amount" : " 3.9",
"Unit" : " g"
}, {
"Nutrient" : "Fiber",
"Amount" : " 0.0",
"Unit" : " g"
}, {
"Title" : "Alcoholic beverage, BUDWEISER, regular, beer"
}]
}
You can do it by using String#lastIndexOf and String#substring. Note that both of these methods have two variants.
public class Main {
public static void main(String[] args) {
String json = "{\n" + " \"nutrients\" : [{\n" + "\n" + " \"Nutrient\" : \"Alcohol, ethyl\",\n"
+ " \"Amount\" : \" 3.9\",\n" + " \"Unit\" : \" g\"\n" + "\n" + " }, {\n" + "\n"
+ " \"Nutrient\" : \"Fiber\",\n" + " \"Amount\" : \" 0.0\",\n"
+ " \"Unit\" : \" g\"\n" + "\n" + " }, {\n" + "\n"
+ " \"Nutrient\" : \"Alcoholic beverage, BUDWEISER, regular, beer\"\n" + "\n" + " }] \n"
+ "}";
int i = json.lastIndexOf("\"Nutrient\"");
// (string before last "Nutrient") + ("Title") + (string after last "Nutrient")
String result = json.substring(0, i) + "\"Title\"" + json.substring(i + "\"Nutrient\"".length());
System.out.println(result);
}
}
Output:
{
"nutrients" : [{
"Nutrient" : "Alcohol, ethyl",
"Amount" : " 3.9",
"Unit" : " g"
}, {
"Nutrient" : "Fiber",
"Amount" : " 0.0",
"Unit" : " g"
}, {
"Title" : "Alcoholic beverage, BUDWEISER, regular, beer"
}]
}
You can achieve this using Jackson.
Needed libs:
Jackson Core: https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.11.0
Jackson Databind: https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.11.0
But you can't change field name. Instead you can add a new one and remove the other.
public static void main(String[] args) throws JsonProcessingException {
String json = ...;
//transform string to jsonnode
JsonNode jsonNode = (new ObjectMapper()).readTree(json);
//get nutrients array node
JsonNode nutrientsNode = jsonNode.get("nutrients");
int lastIndex = nutrientsNode.size() - 1;
//get last node from nutrients and cast to objectnode
ObjectNode lastNutrientObject = (ObjectNode)nutrientsNode.get(lastIndex);
//get Nutrient field value from last nutrient
JsonNode nutrientField = lastNutrientObject.get("Nutrient");
//remove Nutriend field from last nutrient
lastNutrientObject.remove("Nutrient");
//add Title field with node nutrientField into last nutrient
lastNutrientObject.set("Title", nutrientField);
System.out.println(jsonNode.toPrettyString());
}
This looks fairly easy, if you use jackson a well known java library for json.
once you have this on your classpath(may be using the jar or the gradle dependency,etc) you can now do this a couple of ways.
the easiest of which is to probably use objectmapper to parse this data into a pojo and then manipulate the pojo.
or otherwise you could save extra cost and computation by may be parsing this into a JsonNode.
//try to use this instance as much as you can(JACKSON-101)
ObjectMapper mapper = new ObjectMapper();
final JsonNode jsonNode = mapper.readTree("parse_your_json_string_here");
/**
* to get to the nutrients i use `at` because it is nullsafe :D although if performance is a
* concern and `/nutrients` is a common use case you may want to precompile the pointer using <code>
* JsonPointer nutsPointer = JsonPointer.compile("/nutrients");
* </code>
*/
final JsonNode temp = jsonNode.at("/nutrients");
// once done just to be sure we have the right data check that its an arrayNode :D
if (temp.isArray()) {
// if true cast it :D
ArrayNode arrayNode = (ArrayNode) temp;
final JsonNode nutrientsNodeToModify = arrayNode.path(arrayNode.size() - 1);
if (nutrientsNodeToModify.isObject()) {
ObjectNode nutrientsNode = (ObjectNode) nutrientsNodeToModify;
nutrientsNode.set("Title", nutrientsNode.at("/Nutrient"));
nutrientsNode.remove("Nutrient");
}
}
I am trying to implement a function to be able to remove or modify a json object base on a specified json path. For example, if i have a below json string/object:
{
"PersonalDetailsDTO": {
"FirstName": "Mark",
"LastName": "Sully",
"TotalDependent": "2",
"DOB": "19811212",
"SecQuestion": "Some Que",
"SecAnswer": "Some-Ans",
"Mobile": "0123456789",
"Email": "some#validemail.com",
"Title": "Mr",
"EmploymentListDTO": [
{
"Type": "Full-time",
"Probation": true
}
],
"AddressListDTO": [
{
"AddressType": "BUS",
"PostCode": "1234",
"State": "NSW",
"StreetName": "miller",
"StreetNumber": "111",
"StreetType": "Invalid",
"Suburb": "Sydney",
"UnitNumber": "Maximum"
}
]
}
}
And i want to remove element $.PersonalDetailsDTO.AddressListDTO.PostCode.
I've done quite some search, and the one lib i found is JsonPath: http://static.javadoc.io/com.jayway.jsonpath/json-path/2.2.0/com/jayway/jsonpath/JsonPath.html
So i wrote the below code:
public static void main(String[] args) {
// Prints "Hello, World" to the terminal window.
String jsonString = "{\n" +
" \"PersonalDetailsDTO\": {\n" +
" \"FirstName\":\"Mark\",\n" +
" \"LastName\":\"Sully\",\n" +
" \"Title\":\"Mr\",\n" +
" \"DOB\":\"19811201\",\n" +
" \"SecQuestion\":\"Some Ques\",\n" +
" \"SecAnswer\":\"Some-Ans\",\n" +
" \"Email\":\"some#validemail.com\",\n" +
" \"EmploymentListDTO\": [\n" +
" {\n" +
" \"Type\": \"Full-time\",\n" +
" \"Probation\": true\n" +
" }\n" +
" ],\n" +
" \"AddressListDTO\": [\n" +
" {\n" +
" \"AddressType\": \"Residential\",\n" +
" \"PostCode\": \"2345\",\n" +
" \"State\": \"NSW\",\n" +
" \"StreetName\": \"MEL\",\n" +
" \"StreetNumber\": \"2\",\n" +
" \"StreetType\": \"Boulevard\",\n" +
" \"Suburb\": \"Melbourne\",\n" +
" \"UnitNumber\": \"345\"\n" +
" }\n" +
" ]\n" +
" } \n" +
"}";
JSONObject jsonObject = new JSONObject(jsonString);
System.out.println("Before: " + jsonObject.toString());
JsonPath jp = JsonPath.compile("$.PersonalDetailsDTO.AddressListDTO[0].PostCode");
Configuration conf = Configuration.defaultConfiguration();
Object json = conf.jsonProvider().parse(jsonString);
System.out.println("After: " + jp.delete(json, conf).toString());
}
And the console log displays:
Before: {"PersonalDetailsDTO":{"EmploymentListDTO":[{"Type":"Full-time","Probation":true}],"SecAnswer":"Some-Ans","Email":"some#validemail.com","SecQuestion":"Some Ques","FirstName":"Mark","DOB":"19811201","AddressListDTO":[{"StreetName":"MEL","Suburb":"Melbourne","State":"NSW","StreetNumber":"2","UnitNumber":"345","AddressType":"Residential","PostCode":"2345","StreetType":"Boulevard"}],"Title":"Mr","LastName":"Sully"}}
After: {PersonalDetailsDTO={FirstName=Mark, LastName=Sully, Title=Mr, DOB=19811201, SecQuestion=Some Ques, SecAnswer=Some-Ans, Email=some#validemail.com, EmploymentListDTO=[{"Type":"Full-time","Probation":true}], AddressListDTO=[{"AddressType":"Residential","State":"NSW","StreetName":"MEL","StreetNumber":"2","StreetType":"Boulevard","Suburb":"Melbourne","UnitNumber":"345"}]}}
Looks like JsonPath is doing it's job and removing $.PersonalDetailsDTO.AddressListDTO.PostCode. However, there's something very obvious that bothers me:
Looking at the json string produced by .toString() in before and after case, JSONObject API printed a nice string in true json standard format with every double quotes "" present, while the JsonPath .toString produce a customer string format that has some elements in double quote "" while others are not and i can not use it further like JSONObject.
And what i noticed is that although JsonPath claim to accept "java.lang.Object" as parameter in many of its function, what it truely accept is something called "jsonProvider". Not sure if it's causing the weird .toString() behavior.
Anyway, does anyone know how get a nice formatted json string out of JsonPath APIs like remove(), put(), read() and many other? Or to convert the return value to something like JSONObject?
If you know any other Java lib that can do remove/modify element by json path, please feel free to recommand. Thank you!
I don't know JsonPath.
I think you should use jackson which is defacto standard lib when work with JSON in java
aproximate what you are going to do is:
String jsonString = "{"k1": {"k2":"v2"}";
ObjectMapper mapper = new ObjectMapper();
JsonNode actualObj = mapper.readTree(jsonString);
actualObj.at("/k1/k2").getValueAsInt()
and replace getValueAsInt with any other function
I have a below JSON Array and I am trying to parse it but it is giving me an exception:
[{
"response": {
"client": "123456",
"111": {
"data": "0\u00181535480381\u00191535480347\u0018\"voyager\";-1;12;0\u00181535480075\u00191535480069",
"time": "981542121421"
}
}
}]
I am using org.json.JSONArray to parse the above JSON but below code throws exception:
String json =
"[{ \"response\": { \"client\": \"123456\", \"111\": { \"data\": \"0\u00181535480381\u00191535480347\u0018\"voyager\";-1;12;0\u00181535480075\u00191535480069\", \"time\": \"981542121421\" } } }]";
// this line throws exception
JSONArray jsonArray = new JSONArray(json);
Here is the exception I am seeing:
Exception in thread "main" org.json.JSONException: Expected a ',' or '}' at character 81
at org.json.JSONTokener.syntaxError(JSONTokener.java:410)
at org.json.JSONObject.<init>(JSONObject.java:222)
at org.json.JSONTokener.nextValue(JSONTokener.java:344)
at org.json.JSONObject.<init>(JSONObject.java:205)
at org.json.JSONTokener.nextValue(JSONTokener.java:344)
at org.json.JSONObject.<init>(JSONObject.java:205)
at org.json.JSONTokener.nextValue(JSONTokener.java:344)
at org.json.JSONArray.<init>(JSONArray.java:125)
at org.json.JSONArray.<init>(JSONArray.java:157)
What is wrong I am doing here?
Put esacpe charaters around voyager like below.
\\\"voyager\\\"
I tested it worked.
import org.json.JSONArray;
public class Test {
public static void main(String[] args) {
String json = "[{ \"response\": { \"client\": \"123456\", \"111\": { \"data\": \"0\u00181535480381\u00191535480347\u0018\\\"voyager\\\";-1;12;0\u00181535480075\u00191535480069\", \"time\": \"981542121421\" } } }]";
// this line throws exception
JSONArray jsonArray = new JSONArray(json);
}
}
Since it has already escape characters in JOSN you need to double escape in java to retain them.
\"voyager\"
This needs to be double escaped. The parser is seeing the \" as the end of the quote and expecting , or }
Try
\\\"voyager\\\"
In JSON syntax, you were wrong one place - "111", because names must be strings. thus, #NarayanP's code would not run on android system.
Your code throws exception, this is not json's mistake. problems are in assignment line;
String json = "...";
if you put below value into json through http response or file reading
"data": "0\u00181535480381\u00191535480347\u0018\"voyager\";-1;12;0\u00181535480075\u00191535480069"
then actually json's value will be
data: 015354803811535480347"voyager";-1;12;015354800751535480069 [escaped \u0018 etc. by stackoverflow]
if the JSON string contains a semicolon then only the part of the string up until the first semicolon encountered was being returned.
thus, while parsing upper json string, data item will be same as
015354803811535480347"voyager"
Then "-1","12" are JSON syntax errors.
Following is full-code without errors.
String json = "[{\n" +
" \"response\": {\n" +
" \"client\": \"123456\",\n" +
" \"varname111\": {\n" +
" \"data\": \"0\\u00181535480381\\u00191535480347\\u0018\\\"voyager\\\";-1;12;0\\u00181535480075\\u00191535480069\",\n" +
" \"time\": \"981542121421\"\n" +
" }\n" +
" }\n" +
"}]";
JSONArray jsonArray = null;
try {
jsonArray= new JSONArray(json);
} catch (Exception e) {
e.printStackTrace();
}
This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 5 years ago.
This is my Json String and I am trying to fetch the value of Entity.I am a beginner in using JSON.
[
{
"_id": "john",
"preferences": [
{
"Entity": [
"IBM",
"Pfizer"
]
},
{
"Topic": "Pharma"
}
]
}
]
Can anyone help me on this?
try as follow :
JSONObject myjson = new JSONObject(the_json_string);
JSONArray the_json_array = myjson.getJSONArray("profiles");
for more : How to parse a JSON and turn its values into an Array?
import org.json.*;
JSONObject obj = new JSONObject(" .... ");
String pageName = obj.getJSONObject("pageInfo").getString("pageName");
JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
String post_id = arr.getJSONObject(i).getString("post_id");
......
}
May be it may helps you: Parse JSON in Java
You can use gson library. If your input is a JSON string, you first need to parse it using a JsonParser object which returns us a JsonElement which is converted into JsonArray as the input Json is an array. You then extract the first object from it using get(0) and then convert it into a JsonObject, extract preferences element as JsonArray and follow similar procedure to get Entity.
String jsonString = "[" +
" {" +
" \"_id\": john," +
" \"preferences\": [" +
" {" +
" \"Entity\": [" +
" IBM," +
" Pfizer" +
" ]" +
" }," +
" {" +
" \"Topic\": Pharma" +
" }" +
" ]" +
" }" +
"]";
JsonArray jsonArray = new JsonParser().parse(jsonString).getAsJsonArray();
JsonArray preferences = jsonArray.get(0).getAsJsonObject().get("preferences").getAsJsonArray();
JsonArray entity = preferences.get(0).getAsJsonObject().get("Entity").getAsJsonArray();
I am trying to get for example only this:
-68.06993865966797
from a output of this type:
{
"results" : [
{
"elevation" : -68.06993865966797,
"location" : {
"lat" : 27.85061,
"lng" : -95.58962
},
"resolution" : 152.7032318115234
}
],
"status" : "OK"
}
How is it possible to only get the string after
"elevation" :
and end with a comma, but get the string inbetween the colon after elevation until the comma that ends the line
Using regex is not recommended for JSON data. Despite that, I put the two ways (i.e. regex and JSON parser) together as follows:
import java.util.regex.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public static void main(String[] args) throws JSONException {
String JSON_DATA = "{\n"+
" \"results\" : [\n"+
" {\n"+
" \"elevation\" : -68.06993865966797,\n"+
" \"location\" : {\n"+
" \"lat\" : 27.85061,\n"+
" \"lng\" : -95.58962\n"+
" },\n"+
" \"resolution\" : 152.7032318115234\n"+
" }\n"+
" ],\n"+
" \"status\" : \"OK\"\n"+
"}\n"+
"";
// 1. If using REGEX to find all values of "elevation".
Matcher m = Pattern.compile("\"elevation\"\\s+:\\s+(-?[\\d.]+),").matcher(JSON_DATA);
while (m.find()) {
System.out.println("elevation: " + m.group(1));
}
// 2. If using a JSON parser
JSONObject obj = new JSONObject(JSON_DATA);
JSONArray geodata = obj.getJSONArray("results");
for (int i = 0; i < geodata.length(); ++i) {
final JSONObject site = geodata.getJSONObject(i);
System.out.println("elevation: " + site.getDouble("elevation"));
}
}