JSONObject is not getting converted to String properly - java

I am converting JSONObject to String. I am using below code:
String decresponse=obj.getFileWithUtil("Files/v3user22.txt");
System.out.println("Decrypted string is "+decresponse);
JSONObject js = JSONObject(decresponse);
System.out.println("JSON Object is "+js.toString());
Here, i am getting the value of decresponse from a file since the json is very large. Value of decresponse is:
{
"userid":123456,
"status":"SUCCESS",
"name":{
"firstName":"firstname",
"lastName":"lastname"
},
"dob":"03/02/1993",
"gender":"M",
"kycType":"Manual",
"address":{
"permanentAddress":{
"country":"INDIA",
"street_1":"K-26",
"street_2":"",
"city":"North",
"state":"Delhi",
"postal_code":"110052",
"locality":"abc"
},
"correspondenceAddress":{
"country":"INDIA",
"street_1":"abc",
"street_2":"abc",
"city":"ABC",
"state":"Punjab",
"postal_code":"111000",
"locality":"def"
}
},
"docs":[
{
"nameOnDoc":"name",
"verificationStatus":"FAILED",
"kycNameMatch":"SUCCESS",
"docCode":"aadhar",
"docValue":"1898989",
"submittedAs":"AdditionalDoc"
},
{
"nameOnDoc":"abc",
"verificationStatus":"NOT_ATTEMPTED",
"kycNameMatch":"NOT_ATTEMPTED",
"docCode":"pan",
"docValue":"KSKA1234F",
"submittedAs":"AdditionalDoc",
"expiryDate":"03/02/2018"
},
{
"docCode":"voter",
"docValue":"CIBPS2107P",
"submittedAs":"Poi_Poa"
}
],
"agents":[
{
"bankAgentType":"BF",
"agentBranch":"nodia",
"agentDesignation":"agent manager",
"agentEmpcode":"1010111",
"custId":"119990",
"agentId":"",
"agencyType":"CFA",
"agencyName":"internal"
},
{
"bankAgentType":"BC",
"agentBranch":"nodia",
"agentDesignation":"agent manager",
"agentEmpcode":"",
"custId":"119999",
"agentId":"MORPHO-1782",
"agencyType":"VA",
"agencyName":"morpho"
}
],
"relatives":[
{
"relationShip":"FATHER",
"firstName":"firstname",
"lastName":"lastname"
},
{
"relationShip":"MOTHER",
"firstName":"firstname",
"lastName":"lastname"
}
],
"useKycDetails":"UNDER_REVIEW",
"amlflags":{
"sanction":"N",
"pep":"N"
},
"walletflags":{
"upgraded":"1",
"updated":"1",
"blocked":"0"
},
"suspended":"false",
"aadhar_type1_check":"FAILED",
"aadhar_kyc_name_check":"SUCCESS",
"aadharSubmittedAs":"AdditionalDoc",
"aadharVerified":"false",
"panSubmittedAs":"AdditionalDoc",
"panVerified":"false",
"maritalStatus":"MARRIED",
"profession":"PRIVATE_SECTOR_JOB",
"nationality":"INDIAN",
"kycVerificationDate":"04/01/2017",
"declarationPlace":"Delhi",
"dmsInfos":[
{
"type":"",
"dmsid":""
}
],
"aadharAuthCode":"56bd65db0dbc4b2a848841a44eabb54e",
"agriculturalIncome":"100000",
"nonAgriculturalIncome":"50000",
"seedingStatus":"consent_given"
}
But, on converting the json object to string the value comes as below:
{
"panVerified":"false",
"gender":"M",
"userid":123456,
"panSubmittedAs":"AdditionalDoc",
"aadharAuthCode":"56bd65db0dbc4b2a848841a44eabb54e",
"docs":[
{
"kycNameMatch":"SUCCESS",
"verificationStatus":"FAILED",
"nameOnDoc":"name",
"docCode":"aadhar",
"docValue":"1898989",
"submittedAs":"AdditionalDoc"
},
{
"expiryDate":"03/02/2018",
"kycNameMatch":"NOT_ATTEMPTED",
"verificationStatus":"NOT_ATTEMPTED",
"nameOnDoc":"abc",
"docCode":"pan",
"docValue":"KSKA1234F",
"submittedAs":"AdditionalDoc"
},
{
"docCode":"voter",
"docValue":"CIBPS2107P",
"submittedAs":"Poi_Poa"
}
],
"aadhar_type1_check":"FAILED",
"aadharSubmittedAs":"AdditionalDoc",
"useKycDetails":"UNDER_REVIEW",
"kycVerificationDate":"04/01/2017",
"kycType":"Manual",
"profession":"PRIVATE_SECTOR_JOB",
"address":{
"permanentAddress":{
"country":"INDIA",
"street_1":"K-26",
"city":"North",
"street_2":"",
"locality":"abc",
"state":"Delhi",
"postal_code":"110052"
},
"correspondenceAddress":{
"country":"INDIA",
"street_1":"abc",
"city":"ABC",
"street_2":"abc",
"locality":"def",
"state":"Punjab",
"postal_code":"111000"
}
},
"nonAgriculturalIncome":"50000",
"seedingStatus":"consent_given",
"dmsInfos":[
{
"dmsid":"",
"type":""
}
],
"relatives":[
{
"firstName":"firstname",
"lastName":"lastname",
"relationShip":"FATHER"
},
{
"firstName":"firstname",
"lastName":"lastname",
"relationShip":"MOTHER"
}
],
"suspended":"false",
"agents":[
{
"agentId":"",
"agentEmpcode":"1010111",
"custId":"119990",
"agentBranch":"nodia",
"agentDesignation":"agent manager",
"bankAgentType":"BF",
"agencyType":"CFA",
"agencyName":"internal"
},
{
"agentId":"MORPHO-1782",
"agentEmpcode":"",
"custId":"119999",
"agentBranch":"nodia",
"agentDesignation":"agent manager",
"bankAgentType":"BC",
"agencyType":"VA",
"agencyName":"morpho"
}
],
"amlflags":{
"sanction":"N",
"pep":"N"
},
"aadhar_kyc_name_check":"SUCCESS",
"nationality":"INDIAN",
"dob":"03/02/1993",
"walletflags":{
"upgraded":"1",
"blocked":"0",
"updated":"1"
},
"name":{
"firstName":"firstname",
"lastName":"lastname"
},
"aadharVerified":"false",
"maritalStatus":"MARRIED",
"status":"SUCCESS",
"declarationPlace":"Delhi",
"agriculturalIncome":"100000"
}
Why am I getting different values?

Why am I getting different values
Those values are not that different. They simply have key:value pairs in different order.
JSON structure holds key:value pairs where keys are unique. In most cases order of keys is not important so classes like org.json.JSONObject are storing them in internal HashMap which doesn't preserve insertion order (but allows quick access to values).
When toString() is invoked internally it builds String using that HashMap iterator, so order depends on amount of keys and their hashes, not insertion order.
If you want to preserve order consider using other libraries like gson. Your parsing could look like:
JsonParser jsonParser = new JsonParser();
JsonObject js = jsonParser.parse(decresponse).getAsJsonObject();
and js.toString() would result in
{"userid":123456,"status":"SUCCESS","name":{"firstName":"firstname", ... which seems to be what you ware after.

Related

How to get particular json object in from a nested json object which is dynamic based on particular path given which also dynamic

In my application, we have a method that accepts JSON and path which tell us which object we need to get from that JSON. Buth both JSON and path are dynamic, I can't predict that every time we get a request we are getting the same JSON and path.
Example:
{
"company": {
"employees": {
"employee": {
"department": {
"departmentId": 1,
"departmentName": "Developer"
},
"employeeDetails": {
"id": 1,
"name": "abc"
}
}
}
}
}
and the path is company.employees.employee.department. And the requirement is when I get this path I only need that nested JSON object with employee details. Expected output:{
"company": {
"employees": {
"employee": {
"department": {
"departmentId": 1,
"departmentName": "Developer"
}
}
}
}
}
I am confused about your requirement. There is ambiguity in your question. I am thinking that you want to access employeeDetails from the JSON. Here is the solution for that:
var data = {
"company": {
"employees": {
"employee": {
"department": {
"departmentId": 1,
"departmentName": "Developer"
},
"employeeDetails": {
"id": 1,
"name": "abc"
}
}
}
}
}
var employee = data.company.employees.employee // this will store the nested json which is having employeeDetails
console.log(employee)// nested JSON with employeeDetails
console.log(employee.employeeDetails)// this will give you the employeeDetails
The method may look like:
const getData = (json, path) => {
let current = json;
const keys = path.split('.');
for (let key of keys) {
if (!current) {
break;
}
current = current[key];
}
return current;
};
getData(yourJSON, 'key1.key2.key3');

How to make com.fasterxml.jackson print array vertically? [duplicate]

I have data that looks like this:
{
"status": "success",
"data": {
"irrelevant": {
"serialNumber": "XYZ",
"version": "4.6"
},
"data": {
"lib": {
"files": [
"data1",
"data2",
"data3",
"data4"
],
"another file": [
"file.jar",
"lib.jar"
],
"dirs": []
},
"jvm": {
"maxHeap": 10,
"maxPermSize": "12"
},
"serverId": "134",
"version": "2.3"
}
}
}
Here is the function I'm using to prettify the JSON data:
public static String stringify(Object o, int space) {
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(o);
} catch (Exception e) {
return null;
}
}
I am using the Jackson JSON Processor to format JSON data into a String.
For some reason the JSON format is not in the format that I need. When passing the data to that function, the format I'm getting is this:
{
"status": "success",
"data": {
"irrelevant": {
"serialNumber": "XYZ",
"version": "4.6"
},
"another data": {
"lib": {
"files": [ "data1", "data2", "data3", "data4" ],
"another file": [ "file.jar", "lib.jar" ],
"dirs": []
},
"jvm": {
"maxHeap": 10,
"maxPermSize": "12"
},
"serverId": "134",
"version": "2.3"
}
}
}
As you can see under the "another data" object, the arrays are displayed as one whole line instead of a new line for each item in the array. I'm not sure how to modify my stringify function for it to format the JSON data correctly.
You should check how DefaultPrettyPrinter looks like. Really interesting in this class is the _arrayIndenter property. The default value for this property is FixedSpaceIndenter class. You should change it with Lf2SpacesIndenter class.
Your method should looks like this:
public static String stringify(Object o) {
try {
ObjectMapper mapper = new ObjectMapper();
DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
printer.indentArraysWith(new Lf2SpacesIndenter());
return mapper.writer(printer).writeValueAsString(o);
} catch (Exception e) {
return null;
}
}
I don't have enough reputation to add the comment, but referring to the above answer Lf2SpacesIndenter is removed from the newer Jackson's API (2.7 and up), so instead use:
printer.indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE);
Source of the solution

Parsing Json array from webservice to android

I am trying to parse this json data from web service to android using volley.
This is the json array to be parsed.
[
{
"id":"1",
"conf_room_name":"Tadoba"
},
{
"id":"2",
"conf_room_name":"Melghat"
},
{
"id":"3",
"conf_room_name":"Ranthambore"
},
{
"id":"4",
"conf_room_name":"Corbett"
},
{
"id":"5",
"conf_room_name":"Pench"
}
]
[
{
"id":"1",
"area":"Mafatlal"
},
{
"id":"2",
"area":"Andheri"
}
]
[
{
"id":"1",
"type":"Is Personal"
},
{
"id":"2",
"type":"Meeting"
}
]
I am using this code to get the value out of my json array object ot different arraylists.
RequestQueue requestQueue2= Volley.newRequestQueue(this);
// RequestQueue requestQueue3= Volley.newRequestQueue(this);
// Create json array request
JsonArrayRequest jsonArrayRequest=new JsonArrayRequest(Request.Method.POST,"http://170.241.241.198/test.php",new Response.Listener<JSONArray>(){
public void onResponse(JSONArray jsonArray){
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject jsonObject=jsonArray.getJSONObject(i);
stringArray_conf.add(jsonObject.getString("conf_room_name"));
stringArray_area.add(jsonObject.getString("area"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("Error", "Unable to parse json array");
}
});
requestQueue2.add(jsonArrayRequest);
Only 1st array is being filled properly not the other one. I get outofboundsindex exception whenever i try using values from my 2nd arraylist.
All this happens on a button click only i want this to happen when i load my page.
Any help will be appreciated.
Make JSON as Array as below:
[
[
{
"id": "1",
"conf_room_name": "Tadoba"
},
{
"id": "2",
"conf_room_name": "Melghat"
},
{
"id": "3",
"conf_room_name": "Ranthambore"
},
{
"id": "4",
"conf_room_name": "Corbett"
},
{
"id": "5",
"conf_room_name": "Pench"
}
],
[
{
"id": "1",
"area": "Mafatlal"
},
{
"id": "2",
"area": "Andheri"
}
],
[
{
"id": "1",
"type": "Is Personal"
},
{
"id": "2",
"type": "Meeting"
}
]
]
Or Object (easier to reading and understanding):
{
"rooms": [
{
"id": "1",
"conf_room_name": "Tadoba"
},
{
"id": "2",
"conf_room_name": "Melghat"
},
{
"id": "3",
"conf_room_name": "Ranthambore"
},
{
"id": "4",
"conf_room_name": "Corbett"
},
{
"id": "5",
"conf_room_name": "Pench"
}
],
"areas": [
{
"id": "1",
"area": "Mafatlal"
},
{
"id": "2",
"area": "Andheri"
}
],
"types": [
{
"id": "1",
"type": "Is Personal"
},
{
"id": "2",
"type": "Meeting"
}
]
}
PHP code maybe like below:
<?php
$sqlroom = mysql_query("SELECT * FROM `room_table`");
$room_rows = array();
while($r = mysql_fetch_assoc($sqlroom)) {
$room_rows[] = $r;
}
$sqlarea = mysql_query("SELECT * FROM `area_table`");
$area_rows = array();
while($r = mysql_fetch_assoc($sqlarea)) {
$area_rows[] = $r;
}
$sqltype = mysql_query("SELECT * FROM `type_table`");
$type_rows = array();
while($r = mysql_fetch_assoc($sqltype)) {
$type_rows[] = $r;
}
$result = array();
$result["rooms"] = $room_rows;
$result["areas"] = $area_rows;
$result["types"] = $type_rows;
echo json_encode($result);
?>
You seem to be trying to parse three different types of data: conference rooms, areas (which presumably contain conference rooms?) and some information about either one (although it's not clear which). It therefore doesn't make sense to try and store these in a single array as each element contains a different data structure compared to the other two.
If the type is a description of one of the other two objects then it should be compassed within that object, not treated as a separate one. A room doesn't necessarily have to sit within an area but it might also make sense to have it there.
You say you are "pulling all these values from a mysql server and then using php to encode the json data which gives me the structure of the json array" which implies you do not have direct access to the JSON structure, but you should still have access to the PHP structure. The JSON encoder will use the design of the PHP array / object to structure the JSON so, for this to work you need to create more-or-less matching PHP and Java objects at either end of the serialization process.
For instance:
$obj = (object) array
('id' => '1', 'area' => 'Mafatlal', 'rooms' => array
('id' => '1', 'conf_room_name' => 'Tadoba', 'type' => 'Is Personal'),
...
('id' => '2', 'area' => 'Andheri', 'rooms' => array...
);
and
public class Area {
private int id;
private String area;
private Room[] rooms;
}
public class Room {
private int id;
private String conf_room_name;
private String type;
}
Note that, in contrast to the usual Java camel-case naming convention, object variables will usually have to match the incoming JSON variable name (i.e.: conf_room_name instead of confRoomName).
You need to add values using for loop.
for(int i=0;i<jsonArray.length();i++){
try {
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.toString.contains("conf_room_name"))
stringArray_conf.add(jsonObject.getString("conf_room_name"));
else if(jsonObject.toString.contains("area"))
stringArray_area.add(jsonObject.getString("area"));
} catch (JSONException e) {
e.printStackTrace();
}
}

Deserialize JSON with unknown Keys

I'm trying to deserialize a JSON object (from JIRA REST API createMeta) with unknown keys.
{
"expand": "projects",
"projects": [
{
"self": "http://www.example.com/jira/rest/api/2/project/EX",
"id": "10000",
"key": "EX",
"name": "Example Project",
"avatarUrls": {
"24x24": "http://www.example.com/jira/secure/projectavatar?size=small&pid=10000&avatarId=10011",
"16x16": "http://www.example.com/jira/secure/projectavatar?size=xsmall&pid=10000&avatarId=10011",
"32x32": "http://www.example.com/jira/secure/projectavatar?size=medium&pid=10000&avatarId=10011",
"48x48": "http://www.example.com/jira/secure/projectavatar?pid=10000&avatarId=10011"
},
"issuetypes": [
{
"self": "http://www.example.com/jira/rest/api/2/issueType/1",
"id": "1",
"description": "An error in the code",
"iconUrl": "http://www.example.com/jira/images/icons/issuetypes/bug.png",
"name": "Bug",
"subtask": false,
"fields": {
"issuetype": {
"required": true,
"name": "Issue Type",
"hasDefaultValue": false,
"operations": [
"set"
]
}
}
}
]
}
]
}
My problem is: I don't know the keys into "fields" (in the example below "issuetype", "summary", "description", "customfield_12345").
"fields": {
"issuetype": { ... },
"summary": { ... },
"description": { ... },
"customfield_12345": { ... }
}
It would be awesome if I could deserialize it as an array with the key as "id" in my POJO so the above example will looke like the following:
class IssueType {
...
public List<Field> fields;
...
}
class Field {
public String id; // the key from the JSON object e.g. "issuetype"
public boolean required;
public String name;
...
}
Is there a way I can achieve this and wrap in my model? I hope my problem is somehow understandable :)
If you don't know the keys beforehand, you can't define the appropriate fields. The best you can do is use a Map<String,Object>.
If there are in fact a handful of types, for which you can identify a collection of fields, you could write a custom deserializer to inspect the fields and return an object of the appropriate type.
I know it's old question but I also had problem with this and there are results..
Meybe will help someone in future : )
My Response with unknow keys:
in Model Class
private JsonElement attributes;
"attributes": {
"16": [],
"24": {
"165": "50000 H",
"166": "900 lm",
"167": "b.neutr.",
"168": "SMD 3528",
"169": "G 13",
"170": "10 W",
"171": "230V AC / 50Hz"
}
},
So I also checked if jsonElement is jsonArray its empty.
If is jsonObject we have data.
ProductModel productModel = productModels.get(position);
TreeMap<String, String> attrsHashMap = new TreeMap<>();
if (productModel.getAttributes().isJsonObject())
{
for (Map.Entry<String,JsonElement> entry : productModel.getAttributes().getAsJsonObject().entrySet())
{
Log.e("KEYS", "KEYS: " + entry.getKey() + " is empty: " + entry.getValue().isJsonArray());
if (entry.getValue() != null && entry.getValue().isJsonObject())
{
for (Map.Entry<String, JsonElement> entry1 : entry.getValue().getAsJsonObject().entrySet())
{
Log.e("KEYS", "KEYS INSIDE: " + entry1.getKey() + " VALUE: " + entry1.getValue().getAsString());
// and there is my keys and values.. in your case You can get it in upper for loop..
}
}
}
There is a perfectly adequate JSON library for Java that will convert any valid JSON into Java POJOs. http://www.json.org/java/

Having trouble deserializing JSON response with gson

I am using an API where I supply an input string, and it returns some keyword autocompletions and product nodes.
My goal is to deserialize the response and get a list of the autocompletion Strings I can use. I'm trying implement this in an android application with the Retrofit library, which uses gson.
First off, I'm not sure the response I have is a typical JSON response. The 'nodes' item has key / value pairs, but the input string and the autocompletions list don't seem to have keys I can use.
["pol",
["polaroid camera",
"polo",
"polo ralph lauren",
"polo ralph lauren men",
"polar heart rate monitor",
"polaroid",
"polo shirt",
"polar watch",
"police scanner",
"polar"],
[{
"nodes": [{
"alias": "electronics",
"name": "Electronics"
},
{
"alias": "electronics-tradein",
"name": "Electronics Trade-In"
}]
},
{
},
{
},
{
},
{
},
{
},
{
},
{
},
{
},
{
}],
[]]
This is my attempt at the java classes for gson to deserialize to. However, it doesn't work as from what I understand, gson needs the class variables to match the JSON keys (true for Node class but not the rest).
class Response {
String input;
List<String> keywords;
List<Node> nodes;
}
class Node {
String alias;
String name;
}
the json only has a couple of keys in it, this is largely a Json Array.
if you can change the JSON, make it more like this
{
"input" : "pol",
"keywords" : ["polaroid camera","polo",...],
"nodes": [{
"alias": "electronics",
"name": "Electronics"
},
{
"alias": "electronics-tradein",
"name": "Electronics Trade-In"
}]
}

Categories