I have json array from server response like this.
[
{
"idApp" : "001"
"AppName" : "Test App 1"
},
{
"idApp" : "002"
"AppName" : "Test App 2"
},
{
"idApp" : "003"
"AppName" : "Test App 3"
},
{
"idApp" : "004"
"AppName" : "Test App 4"
}
]
i just want to know the position of this object in jsonarray programatically
{
"idApp" : "003"
"AppName" : "Test App 3"
}
This should work for you
for(int i = 0 ; i < arguments.length(); i++){
if(arguments.getObject(i).get("idApp").asString().equals("003"))
System.out.println("Found it : " + i);
}
You forget , in each object in json string after each data like below :
{
"idApp" : "003",
"AppName" : "Test App 3"
}
By the way to get postion match 003 in idApp we can use Gson library http://mvnrepository.com/artifact/com.google.code.gson/gson/2.3.1
Add dependency in pom.xml :
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3.1</version>
</dependency>
Create modal class like your json object :
public class Modal {
private String idApp;
private String AppName;
public String getIdApp() {
return idApp;
}
public void setIdApp(String idApp) {
this.idApp = idApp;
}
public String getAppName() {
return AppName;
}
public void setAppName(String AppName) {
this.AppName = AppName;
}
}
Now convert json string to array of object and loop over array and find match object like below :
public class JsonUtils {
public static void main(String[] args) {
System.out.println("Position for 003 is = " + new JsonUtils().getPositionFromJsonString());
}
public int getPositionFromJsonString() {
Gson gson = new Gson();
String jsonString = "["
+ " {"
+ " \"idApp\" : \"001\","
+ " \"AppName\" : \"Test App 1\""
+ " },"
+ ""
+ " {"
+ " \"idApp\" : \"002\","
+ " \"AppName\" : \"Test App 2\""
+ " },"
+ ""
+ " {"
+ " \"idApp\" : \"003\","
+ " \"AppName\" : \"Test App 3\""
+ " },"
+ ""
+ " {"
+ " \"idApp\" : \"004\","
+ " \"AppName\" : \"Test App 4\""
+ " }"
+ ""
+ "]";
Modal[] modals = gson.fromJson(jsonString, Modal[].class);
int pos = -1;
for (Modal m : modals) {
pos++;
if ("003".equalsIgnoreCase(m.getIdApp())) {
return pos;
}
}
return -1;
}
}
You can do something like that to remove the specefic jsonObject from jsonArray.
//find the value in your jsonarray
for (int i = 0; i < jsonarray.length; ++i)
{
JSONObject rec =jsonarray.getJSONObject(i);
//check the condition if the given id is associated with the object then remove it
if(rec.getString("idApp").equals("your_passedId")
{
jsonarray.remove(i)
}
}
May be late, but it may help to someone
int index = 0;
while (index < yourArray.length()) {
JSONObject object = yourArray.optJSONObject(index);
if (object != null) {
if (/*your condition is true*/ true){
yourArray.remove(index);
index--;
}
}
index++;
}
Related
how can i create a JSON string from Json array of objects like below in Java using JSON object
{
header: [
{
"key" : "numberOfRecords",
"value" : "122"
"valueDataType" : "string"
},
{
"key" : "g_udit"
"value" : "1"
"valueDataType" : "string"
},
{
"key": "userNameId"
"value" : "155"
"valueDataType : "string"
}
]
}
expected JSON output requires only values
{
header :
{
"numberOfRecords" : "122",
"g_udit" : "1",
"userNameId" : "155"
}
}
Use JSON query language to transform the JSON structure. A single Josson query statement can do the job.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(
"{" +
" \"header\": [" +
" {" +
" \"key\" : \"numberOfRecords\"," +
" \"value\" : \"122\"," +
" \"valueDataType\" : \"string\"" +
" }," +
" { " +
" \"key\" : \"g_udit\"," +
" \"value\" : \"1\"," +
" \"valueDataType\" : \"string\"" +
" }," +
" {" +
" \"key\": \"userNameId\"," +
" \"value\" : \"155\"," +
" \"valueDataType\" : \"string\"" +
" }" +
" ]" +
"}");
JsonNode node = josson.getNode("map(header.map(key::value).mergeObjects())");
Output
{
"header" : {
"numberOfRecords" : "122",
"g_udit" : "1",
"userNameId" : "155"
}
}
First of all you should use any json framework to read and write files. You can use jacskon-utils to use Jackson and make it much simpler to use.
Then you have to define the data classes for input and output types. And finally, convert the data.
#Getter
class InputData {
#JsonProperty("header")
private List<Header> headers;
#Getter
public static class Header {
private String key;
private String value;
private String valueDataType;
}
}
#Setter
class OutputData {
#JsonProperty("header")
private Map<String, String> headers;
}
public static void main(String... args) throws Exception {
InputData inputData = readData(new File("c:/in.json"));
OutputData outputData = createOutputData(inputData);
writeData(new File("c:/out.json"), outputData);
}
private static InputData readData(File file) throws Exception {
try (InputStream in = new FileInputStream(file)) {
return JacksonUtils.readValue(in, InputData.class);
}
}
private static void writeData(File file, OutputData outputData) throws Exception {
try (OutputStream out = new FileOutputStream(file)) {
JacksonUtils.prettyPrint().writeValue(outputData, out);
}
}
private static OutputData createOutputData(InputData inputData) {
Map<String, String> headers = new LinkedHashMap<>();
inputData.getHeaders().forEach(header -> headers.put(header.getKey(), header.getValue()));
OutputData outputData = new OutputData();
outputData.setHeaders(headers);
return outputData;
}
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
I have XML which can be of any structure like below. Therefore there is no POJO class for instantiation. As you can see I have nested arrays (in this case reservations is an array of two reservation and every reservation have simple elements and arrays of rooms - but that is only example - there may be more arrays and nested arrays).
<reservations>
<reservation>
<id>1318504</id>
<add_date>2020-12-10 12:48:09</add_date>
<rooms>
<room>
<id>28902</id>
<floor>2</floor>
</room>
<room>
<id>28903</id>
<floor>3</floor>
</room>
</rooms>
</reservation >
<reservation>
<id>1318501</id>
<add_date>2021-05-07 07:47:05</add_date>
<rooms>
<room>
<id>5</id>
<floor>25</floor>
</room>
<room>
<id>6</id>
</room>
</rooms>
</reservation>
</reservations>
I need to convert it to Json as:
{
"reservations":[
{
"id":"1318504",
"add_date":"2020-12-10 12:48:09",
"rooms":[
{
"id":"28902",
"floor":2
},
{
"id":"28903",
"floor":3
}
]
},
{
"id":"1318501",
"add_date":"2021-05-07 07:47:05",
"rooms":[
{
"id":"5",
"floor":25
},
{
"id":"6"
}
]
}
]
}
I have read lots of topic about converting XML to Json. I tried something like:
json.org
JSONObject xmlJSONObj = XML.toJSONObject(xmlString);
jackson
JsonNode node = new XmlMapper().readTree(xmlContent);
underscore-java
String jsonString = U.xmlToJson(xmlContent)
and so on. Bu the result, in best case is like:
{
"reservations":{
"reservation":[
{
"rooms":{
"room":[
{
"id":28902,
"floor":2
},
{
"id":28903,
"floor":3
}
]
},
"add_date":"2020-12-10 12:48:09",
"id":1318504
},
{
"rooms":{
"room":[
{
"id":5,
"floor":25
},
{
"id":6
}
]
},
"add_date":"2021-05-07 07:47:05",
"id":1318501
}
]
}
}
I don't need nodes like reservation and room. Could you help me how can I solve this problem? I can manipulate with xml or json, but the form without these nodes is my target.
The solution:
import com.github.underscore.U;
String xml = "<reservations>\n"
+ " <reservation>\n"
+ " <id>1318504</id>\n"
+ " <add_date>2020-12-10 12:48:09</add_date>\n"
+ " <rooms> \n"
+ " <room>\n"
+ " <id>28902</id>\n"
+ " <floor>2</floor>\n"
+ " </room> \n"
+ " <room>\n"
+ " <id>28903</id>\n"
+ " <floor>3</floor>\n"
+ " </room>\n"
+ " </rooms>\n"
+ " </reservation >\n"
+ " <reservation>\n"
+ " <id>1318501</id>\n"
+ " <add_date>2021-05-07 07:47:05</add_date>\n"
+ " <rooms>\n"
+ " <room>\n"
+ " <id>5</id>\n"
+ " <floor>25</floor>\n"
+ " </room>\n"
+ " <room>\n"
+ " <id>6</id>\n"
+ " </room>\n"
+ " </rooms>\n"
+ " </reservation>\n"
+ "</reservations>";
Map<String, Object> map = U.fromXmlMap(xml);
U.set(map, "reservations", U.get(map, "reservations.reservation"));
List<Map<String, Object>> list = U.get(map, "reservations");
for (Map<String, Object> item : list) {
U.set(item, "rooms", U.get(item, "rooms.room"));
}
System.out.println(U.toJson(map));
Result:
{
"reservations": [
{
"id": "1318504",
"add_date": "2020-12-10 12:48:09",
"rooms": [
{
"id": "28902",
"floor": "2"
},
{
"id": "28903",
"floor": "3"
}
]
},
{
"id": "1318501",
"add_date": "2021-05-07 07:47:05",
"rooms": [
{
"id": "5",
"floor": "25"
},
{
"id": "6"
}
]
}
],
"#omit-xml-declaration": "yes"
}
You may be able to use json:Array="true" in the array - and the JsonConvert will interpret it correctly.
https://www.newtonsoft.com/json/help/html/ConvertXmlToJsonForceArray.htm
I'd like to display values from my JSON just for testing purposes, but I've received literally nothing. Where can be an issue? The link in Utils is correctly for sure, I've runned it on my browser, and everything was good.
Here's the code
Utils class
public class WeatherUtils {
public WeatherUtils(){}
public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){
ArrayList<Weather> weatherList = new ArrayList<>();
try {
JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");
JSONArray array = reader.getJSONArray("list");
for (int i = 0; i<array.length(); i++){
JSONObject secondReader = array.getJSONObject(i);
JSONObject dataObject = secondReader.getJSONObject("main");
for (int j = 0; j<dataObject.length(); j++){
currentTemp = dataObject.getDouble("temp");
minTemp = dataObject.getDouble("temp_min");
maxTemp = dataObject.getDouble("temp_max");
airPressure = dataObject.getDouble("pressure");
}
weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
}
} catch (JSONException e) {
e.printStackTrace();
}
return weatherList;
}
}
MainActivity
Double a,b,c,d;
a = 0.0;
b = 0.0;
c = 0.0;
d = 0.0;
ArrayList<Weather> weathers = WeatherUtils.getHourlyData(a,b,c,d);
System.out.println(weathers);
JSON structure
{
"cod": "200",
"message": 0.0074,
"cnt": 40,
"list": [
{
"dt": 1559131200,
"main": {
"temp": 22.1,
"temp_min": 21.32,
"temp_max": 22.1,
"pressure": 1012.31,
"sea_level": 1012.31,
"grnd_level": 976.84,
"humidity": 92,
"temp_kf": 0.78
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": {
"all": 89
},
"wind": {
"speed": 3.08,
"deg": 213.025
},
"rain": {
"3h": 0.875
},
"sys": {
"pod": "d"
},
"dt_txt": "2019-05-29 12:00:00"
},
{
Of course, there are more data. I've posted one "block"
How I may fix that?
Well, given that you just want to "test" the json parsing, you have few options but let's go with a simple one. But first, I would say to extract the parser and put it in its own class/method so it becomes easier to test, something like this:
public class WeatherUtils {
public WeatherUtils(){}
public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){
final ArrayList<Weather> weatherList = new ArrayList<>();
try {
final JSONObject response = httpCall();
weatherList = mapWeatherResponse(response);
} catch (JSONException e) {
e.printStackTrace();
}
return weatherList;
}
public static List<Weather> mapWeatherResponse(JSONObject reader){
final ArrayList<Weather> weatherList = new ArrayList<>();
JSONArray array = reader.getJSONArray("list");
for (int i = 0; i<array.length(); i++){
JSONObject secondReader = array.getJSONObject(i);
JSONObject dataObject = secondReader.getJSONObject("main");
for (int j = 0; j<dataObject.length(); j++){
currentTemp = dataObject.getDouble("temp");
minTemp = dataObject.getDouble("temp_min");
maxTemp = dataObject.getDouble("temp_max");
airPressure = dataObject.getDouble("pressure");
}
weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
}
}
}
Test the response parser with a junit test:
You can create a junit test like this:
public class WeatherUtilsTest {
#Test
public void parserResponseTEst() {
final List<String> expectedResponse = new ArrayList<>();
//fill the expectedResponse with the correspondent values
final String json = "{\n" +
" \"cod\": \"200\",\n" +
" \"message\": 0.0074,\n" +
" \"cnt\": 40,\n" +
" \"list\": [\n" +
" {\n" +
" \"dt\": 1559131200,\n" +
" \"main\": {\n" +
" \"temp\": 22.1,\n" +
" \"temp_min\": 21.32,\n" +
" \"temp_max\": 22.1,\n" +
" \"pressure\": 1012.31,\n" +
" \"sea_level\": 1012.31,\n" +
" \"grnd_level\": 976.84,\n" +
" \"humidity\": 92,\n" +
" \"temp_kf\": 0.78\n" +
" },\n" +
" \"weather\": [\n" +
" {\n" +
" \"id\": 500,\n" +
" \"main\": \"Rain\",\n" +
" \"description\": \"light rain\",\n" +
" \"icon\": \"10d\"\n" +
" }\n" +
" ],\n" +
" \"clouds\": {\n" +
" \"all\": 89\n" +
" },\n" +
" \"wind\": {\n" +
" \"speed\": 3.08,\n" +
" \"deg\": 213.025\n" +
" },\n" +
" \"rain\": {\n" +
" \"3h\": 0.875\n" +
" }\n" +
" }]\n" +
" }";
final List<String> response = WeatherUtils.mapWeatherResponse(new JSONObject(json));
assertEquals(expectedResponse, response);
}
}
There is nothing wrong with the JSONObject parser you are doing. You mentioned the link you are using in Utils is correct, do you get a proper response when you test it in your browser, postman, insomnia?
OBS JSONObject reader = new JSONObject("https://api..."); does not fetch anything, what you are doing there is creating a JSONObject from the given String, i.e. "https://....". To fetch the data you need to implement some http client. Here is an example https://stackoverflow.com/a/4457526/761668
You're not getting the response from the server, you're trying to initialize a JSONObject with the URL.
To retrieve it you should replace this line:
JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");
with this code:
HttpURLConnection conn = null;
String data = null;
try {
conn = (HttpURLConnection) new URL("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...").openConnection();
conn.setRequestMethod("GET");
conn.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
data = sb.toString();
} catch (Exception e) {
// do something
} finally {
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex) {
// do something
}
}
}
JSONObject reader = new JSONObject(data);
This code will retrieve the JSON object from the endpoint and convert it to a String object. Then you can create a JSONObject with it.
I have a json in a JsonObject such as:
"customer": {
"full_name": "John John",
"personal": {
"is_active": "1",
"identifier_info": {
"hobbies": [
"skiing",
"traveling"
],
"user_id": "1234",
"office_id": "2345"
}
}
}
Is there a way to modify the JsonObject so as to remove the hobbies completely from the identifier_info and leave the rest untouched and then add the contents of hobbies the same way as the others? i.e.
"customer": {
"full_name": "John John",
"personal": {
"is_active": "1",
"identifier_info": {
"skiing":"expert",
"traveling":"rarely",
"user_id": "1234",
"office_id": "2345"
}
}
}
Find the full implementation for removing the JSON Array "hobbies" and to insert them in the parent JSON Object directly.
public class ProcessJSONString {
String data ="{\"customer\": { \n" +
" \"full_name\": \"John John\", \n" +
" \"personal\": { \n" +
" \"is_active\": \"1\", \n" +
" \"identifier_info\": { \n" +
" \"hobbies\": [ \n" +
" \"skiing\",\n" +
" \"traveling\"\n" +
" ], \n" +
" \"user_id\": \"1234\", \n" +
" \"office_id\": \"2345\"\n" +
" } \n" +
" } \n" +
"}} ";
public void processData() {
try {
JSONObject result = new JSONObject(data);
JSONObject customer = result.getJSONObject("customer");
JSONObject personal = customer.getJSONObject("personal");
JSONObject identifierInfo =
personal.getJSONObject("identifier_info");
JSONArray hobbies = identifierInfo.getJSONArray("hobbies");
identifierInfo.remove("hobbies");
//Under the assumption the tags will be added by the user, the code has been inserted.
identifierInfo.put("skiing","expert");
identifierInfo.put("traveling","rarely");
} catch (JSONException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ProcessJSONString instance = new ProcessJSONString();
instance.processData();
}
}
That should be no problem, using JsonObject's remove() method. It returns the removed JsonElement. Assuming the original json is a JsonObject called customer:
JsonObject identifierInfo = customer.getAsJsonObject("personal").getAsJsonObject("identifier_info");
JsonArray hobbies = (JsonArray) identifierInfo.remove("hobbies");
after that you can just add the hobbies to the identifierInfo and get the desired result:
for (JsonElement aHobby : hobbies) {
identifierInfo.addProperty(aHobby.getAsString(), "expert");
}
don't forget to add null checks as needed.