Parse and Sort JSON data using java - java

I am looking to parse the following array using org.json.simple library and having difficulty. Could someone please look at my json file and code and advise what I am doing wrong
{
"Company": [
{
"Department": "Engineering",
"Employee": [
{
"EmpName": "Jack",
"EmpCode": "8",
"Type": "Permanent"
}, {
"EmpName": "John",
"EmpCode": "45",
"Type": "Permanent"
}, {
"EmpName": "Ron",
"EmpCode": "9",
"Type": "Contract"
}, {
"EmpName": "Jin",
"EmpCode": "6",
"Type": "Permanent"
}, {
"EmpName": "Jill",
"EmpCode": "",
"Type": "Retired"
}, {
"EmpName": "Sam",
"EmpCode": "89",
"Type": "Permanent"
}, {
"EmpName": "Jonathan",
"EmpCode": "66",
"Type": "Permanent"
}, {
"EmpName": "Craig",
"EmpCode": "",
"Type": "Ex-Employee"
}, {
"EmpName": "Son Hui",
"EmpCode": "4",
"Type": "Permanent"
}, {
"EmpName": "Joshua",
"EmpCode": "12",
"Type": "Contract"
}, {
"EmpName": "Tulip",
"EmpCode": "70",
"Type": "Contract"
}
]
}, {
"Department": "IT",
"Employee": [
{
"EmpName": "Nico",
"EmpCode": "50",
"Type": "Resigned"
}, {
"EmpName": "Phil",
"EmpCode": "103",
"Type": "Resigned"
}
]
}
]
}
Notice that a few EmpCode fields are also blank. How should I handle them. Also, I need to be able to re-arrange the data while displaying it, I mean I need to sort the data based on EmpCode or Type.
The code I wrote to parse the above json is mentioned below:
package amazontesting;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
public class json {
private static final String filePath = /emp.json";
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader(filePath));
JSONObject jsonObject = (JSONObject) obj;
String name = (String) jsonObject.get("Department");
//String suites = (String) jsonObject.get("Company");
JSONArray slideContent = (JSONArray) jsonObject.get("Department");
Iterator i = slideContent.iterator();
while (i.hasNext()) {
System.out.println(i.next());
String title = (String) jsonObject.get("Employee");
System.out.println(title);
}
}
catch (FileNotFoundException e)
{}
catch(IOException e)
{}
catch(ParseException e)
{}
}
}

Looks like you have misunderstanding of how Json structure works and what kind of objects it's may contains.
For example, what do you think you do in this piece of code?
JSONArray slideContent = (JSONArray) jsonObject.get("Department");
Iterator i = slideContent.iterator();
Looks like you trying to get json object with name "Department", but it's not an JsonArray, it's a String.
"Department": "Engineering"
//Writing code "jsonObject.get("Department")"
//you will get string "Engineering"
//this code will be correct
(JSONArray) jsonObject.get("Employee")
//because a json value for name "Employee" it's an JsonArray

Related

How can I more efficiently find all of targeted objects in JSON File?

I have a JSON file that is serving as data storage for my application:
{
"users": {
"instructors": [
{
"id": 1234,
"password": "hello1234",
"name": "Teacher 1",
"listOfCourses": [
{
"id": 3622,
"name": "CS 3622",
"studentsEnrolled": [
{
"id": 1002,
"name": "Student 1",
"dateOfBirth": "00/11/2222"
},
{
"id": 1002,
"name": "Student 2",
"dateOfBirth": "00/11/2222"
}
]
},
{
"id": 4306,
"name": "CS 4306",
"studentsEnrolled": [
{
"id": 1002,
"name": "Student 3",
"dateOfBirth": "33/44/55"
},
{
"id": 1002,
"name": "Jay Wright",
"dateOfBirth": "33/44/5555"
}
]
}
]
}
],
"admin": [
{
"userId": 12345,
"userPassword": "hello12345",
"name": "Admin 1"
},
{
"userId": 123456,
"userPassword": "hello12345",
"name": "Admin 2"
}
]
}
}
The above file is passed into a Java.io.File object. I am trying to find a more time efficient manner of retrieving all the course objects from the JSON file. I am currently using Jackson and have implemented the below method:
public List<Course> retrieveAll() throws IOException {
if (this.allCourses != null) {
return this.allCourses;
}
List<Course> listOfAllCourses = new ArrayList<>();
JsonNode instructors = root.get("users").get("instructors");
ArrayNode arrayNode = (ArrayNode) instructors;
Iterator<JsonNode> iter = arrayNode.iterator();
while (iter.hasNext()) {
JsonNode currentInstructor = iter.next();
ArrayNode arrayNodeOfCourses = (ArrayNode) currentInstructor.get("listOfCourses");
Iterator<JsonNode> iter2 = arrayNodeOfCourses.iterator();
while (iter2.hasNext()) {
Course currentCourse = objectMapper.treeToValue(iter2.next(), Course.class);
currentCourse.setCourseInstructor(objectMapper.treeToValue(currentInstructor, Instructor.class));
listOfAllCourses.add(currentCourse);
}
}
this.allCourses = listOfAllCourses;
return listOfAllCourses;
}
However, I am looking for a more efficient way of doing this hopefully without nested loops as that can give the method a time efficiency of O(nm).

Validating json payload against swagger file - json-schema-validator

I am trying to validate a json payload against a swagger file that contains the service agreement. I am using the json-schema-validator(2.1.7) library to achieve this, but at the moment it's not validating against the specified patterns or min/max length.
Java Code:
public void validateJsonData(final String jsonData) throws IOException, ProcessingException {
ClassLoader classLoader = getClass().getClassLoader();
File jsonSchemaFile = new File (classLoader.getResource("coachingStatusUpdate.json").getFile());
String jsonSchema = new String(Files.readAllBytes(jsonSchemaFile.toPath()));
final JsonNode dataNode = JsonLoader.fromString(jsonData);
final JsonNode schemaNode = JsonLoader.fromString(jsonSchema);
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
JsonValidator jsonValidator = factory.getValidator();
ProcessingReport report = jsonValidator.validate(schemaNode, dataNode);
System.out.println(report);
if (!report.toString().contains("success")) {
throw new ProcessingException (
report.toString());
}
}
Message I am sending through
{
"a": "b",
"c": "d",
"e": -1,
"f": "2018-10-30",
"g": "string" }
The swagger definition:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Test",
"termsOfService": "http://www.test.co.za",
"license": {
"name": "Test"
}
},
"host": "localhost:9001",
"basePath": "/test/",
"tags": [
{
"name": "controller",
"description": "Submission"
}
],
"paths": {
"/a": {
"put": {
"tags": [
"controller"
],
"summary": "a",
"operationId": "aPUT",
"consumes": [
"application/json;charset=UTF-8"
],
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"in": "body",
"name": "aRequest",
"description": "aRequest",
"required": true,
"schema": {
"$ref": "#/definitions/aRequest"
}
}
],
"responses": {
"200": {
"description": "Received",
"schema": {
"$ref": "#/definitions/a"
}
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"408": {
"description": "Request Timeout"
},
"500": {
"description": "Generic Error"
},
"502": {
"description": "Bad Gateway"
},
"503": {
"description": "Service Unavailable"
}
}
}
}
},
"definitions": {
"aRequest": {
"type": "object",
"required": [
"a",
"b",
"c",
"d"
],
"properties": {
"a": {
"type": "string",
"description": "Status",
"enum": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h"
]
},
"aReason": {
"type": "string",
"description": "Reason",
"enum": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n"
]
},
"correlationID": {
"type": "integer",
"format": "int32",
"description": "",
"minimum": 1,
"maximum": 9999999
},
"effectiveDate": {
"type": "string",
"format": "date",
"description": ""
},
"f": {
"type": "string",
"description": "",
"minLength": 1,
"maxLength": 100
}
}
},
"ResponseEntity": {
"type": "object",
"properties": {
"body": {
"type": "object"
},
"statusCode": {
"type": "string",
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"419",
"420",
"421",
"422",
"423",
"424",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"509",
"510",
"511"
]
},
"statusCodeValue": {
"type": "integer",
"format": "int32"
}
}
}
}
}
As you can see I am sending through a correlationID of -1, which should fail validation, but at the moment is's returning as successful:
com.github.fge.jsonschema.report.ListProcessingReport: success
I suggest using this library, which worked for me:
https://github.com/bjansen/swagger-schema-validator
Example:
invalid-pet.json
{
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"named": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
My SchemaParser:
#Component
public class SchemaParser {
private Logger logger = LoggerFactory.getLogger(getClass());
public boolean isValid(String message, Resource schemaLocation) {
try (InputStream inputStream = schemaLocation.getInputStream()) {
SwaggerValidator validator = SwaggerValidator.forJsonSchema(new InputStreamReader(inputStream));
ProcessingReport report = validator.validate(message, "/definitions/Pet");
return report.isSuccess();
} catch (IOException e) {
logger.error("IOException", e);
return false;
} catch (ProcessingException e) {
e.printStackTrace();
return false;
}
}
}
A test:
#Test
void shouldFailValidateWithPetstoreSchema() throws IOException {
final Resource validPetJson = drl.getResource("http://petstore.swagger.io/v2/swagger.json");
try (Reader reader = new InputStreamReader(validPetJson.getInputStream(), UTF_8)) {
final String petJson = FileCopyUtils.copyToString(reader);
final boolean valid = schemaParser.isValid(petJson, petstoreSchemaResource);
assertFalse(valid);
}
}
json-schema-validator seems to work with pure JSON Schema only. OpenAPI Specification uses an extended subset of JSON Schema, so the schema format is different. You need a library that can validate specifically against OpenAPI/Swagger definitions, such as Atlassian's swagger-request-validator.

Recursive JSON data parsing using GSON

Sometime we may have JSON data like,
[
{
"Name": "Fruits",
"Quantity": "10",
"isCheckBox": false,
"List": [
{
"Name": "Mango",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Apple",
"Quantiy": "10",
"iScheckBox": false,
"List": [
{
"Name": "Simla",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Fuji",
"Quantiy": "10",
"iScheckBox": false,
"List": []
}
]
}
]
},
{
"Name": "Fruits",
"Quantity": "10",
"isCheckBox": false,
"List": [
{
"Name": "Mango",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Apple",
"Quantiy": "10",
"iScheckBox": false,
"List": [
{
"Name": "Simla",
"Quantiy": "10",
"iScheckBox": true,
"List": null
},
{
"Name": "Fuji",
"Quantiy": "10",
"iScheckBox": false,
"List": []
}
]
}
]
}
]
Note : If the isCheckBox value is false then will check the list values to get the inner objects.
Don't know the end of depth level, it may end, or goes on. How to define the POJO class for JSON data like this?
public class Shopping
{
private Fruits Fruits;
private String Vegetables;
public Fruits getFruits ()
{
return Fruits;
}
public void setFruits (Fruits Fruits)
{
this.Fruits = Fruits;
}
public String getVegetables ()
{
return Vegetables;
}
public void setVegetables (String Vegetables)
{
this.Vegetables = Vegetables;
}
#Override
public String toString()
{
return "ClassPojo [Fruits = "+Fruits+", Vegetables = "+Vegetables+"]";
}}
This will be enough for the above given sample. Please try
Actually the solution is very simple,
Here is entity,
public class FruitsEntity {
String Name;
String Quantity;
boolean isCheckBox;
ArrayList<FruitsEntity> List;
}
And you can parse using,
Gson gson = new Gson();
ArrayList<FruitsEntity> nestEntities = gson.fromJson(jsonData, new TypeToken<ArrayList<FruitsEntity>>() {
}.getType());

how to parse the json response which starts with an array

response:
[
{
"id": "e9299032e8a34d168def176af7d62da3",
"createdAt": "Nov 8, 2017 9:46:40 AM",
"model": {
"id": "eeed0b6733a644cea07cf4c60f87ebb7",
"name": "color",
"app_id": "main",
"created_at": "May 11, 2016 11:35:45 PM",
"model_version": {}
},
"input": {
"id": "df6eae07cd86483f811c5a2202e782eb",
"data": {
"concepts": [],
"metadata": {},
"image": {
"url": "http://www.sachinmittal.com/wp-content/uploads/2017/04/47559184-image.jpg"
}
}
},
"data": [
{
"hex": "#f59b2d",
"webSafeHex": "#ffa500",
"webSafeColorName": "Orange",
"value": 0.0605
},
{
"hex": "#3f1303",
"webSafeHex": "#000000",
"webSafeColorName": "Black",
"value": 0.2085
},
{
"hex": "#a33303",
"webSafeHex": "#8b0000",
"webSafeColorName": "DarkRed",
"value": 0.3815
},
{
"hex": "#000000",
"webSafeHex": "#000000",
"webSafeColorName": "Black",
"value": 0.34275
},
{
"hex": "#f7ce93",
"webSafeHex": "#ffdead",
"webSafeColorName": "NavajoWhite",
"value": 0.00675
}
],
"status": {}
}
]
need to parse this reponse in json. Please help me out.
You can try something like this..
try{
JSONArray array= new JSONArray(Yourresponse);
for(int i=0; i<=array.length();i++){
JSONObject jsonObject=array.getJSONObject(i);
String id= jsonObject.getString("id");
String created_at= jsonObject.getString("createdAt");
String model_id = jsonObject.getJSONObject("model").getString("id");
String app_id=jsonObject.getJSONObject("model").getString("app_id");
//So On... Depends on your requirements. It's just an idea!
}
}
catch (Exception e){
e.printStackTrace();
}

Exception Cast JsonObject

How can I read this file using JsonObject and JsonArray? And how can I retrieve the typeId value?
{
"mockup": {
"controls": {
"control": [
{
"ID": "5",
"measuredH": "400",
"measuredW": "450",
"properties": {
"bold": "true",
"bottomheight": "0",
"italic": "true",
"size": "20",
"text": "Test",
"topheight": "26",
"underline": "true",
"verticalScrollbar": "true"
},
"typeID": "TitleWindow",
"x": "50",
"y": "50",
"zOrder": "0"
},
{
"ID": "6",
"measuredH": "27",
"measuredW": "75",
"properties": {
"align": "left",
"bold": "true",
"color": "0",
"italic": "true",
"menuIcon": "true",
"size": "18",
"state": "selected",
"text": "OK",
"underline": "true"
},
"typeID": "Button",
"x": "67",
"y": "85",
"zOrder": "1"
}
]
},
"measuredH": "450",
"measuredW": "500",
"mockupH": "400",
"mockupW": "450",
"version": "1.0"
}
}
I'm using this code:
import org.json.JSONException;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Main {
private static final String _strDesktopDirectory = System.getProperty("user.home") + "/Desktop";
public static void main(String[] args) {
JSONParser _jspMyJsonParser = new JSONParser();
JFileChooser _fcMyFileChooser = new JFileChooser("Open JSON File");
FileNameExtensionFilter _fneJsonFilter = new FileNameExtensionFilter("JSON Files (*.json)", "json");
_fcMyFileChooser.setFileFilter(_fneJsonFilter);
int _iReturnFile = _fcMyFileChooser.showOpenDialog(_fcMyFileChooser);
_fcMyFileChooser.setCurrentDirectory(new File(_strDesktopDirectory));
if (_iReturnFile == JFileChooser.APPROVE_OPTION) {
try {
String _strSelectedFile = _fcMyFileChooser.getSelectedFile().toString();
Object _oMyObject = _jspMyJsonParser.parse(new FileReader(_strSelectedFile));
// Exception Here.
JSONObject _jsnoMockup = (JSONObject) _oMyObject;
_jsnoMockup = (JSONObject) _jsnoMockup.get("mockup");
JSONObject _jsnoControls = (JSONObject) _jsnoMockup.get("controls");
System.out.println("Mockup: " + _jsnoMockup);
System.out.println("Controls: " + _jsnoControls);
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
} else {
System.out.println("Close");
System.exit(0);
}
}
}
The error is:
Exception in thread "main" java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.JSONObject
Note: I don't have any experience with Java.
The method getJSONfromURL returns the JSON of the given URL and that works just fine but the error is in JSONArray jsonArray = (JSONArray)jsonobject;
It gives the following error: cannot cast JSONObject to JSONArray. I've also tried this: JSONArray jsonArray = (JSONObject)(JSONArray)jsonobject;
I can't figure out what I'm doing wrong.
try with below one
JSONArray jsonArray = new JSONArray();
jsonArray = jsonObject.getJSONObject("mockup").getJSONObject("controls").getJSONArray("control");
for(i=0;i<jsonArray.lenght();i++){
System.out.println(jsonArray.getJSONObject(i).getString("typeID"));
}

Categories

Resources