How to update Rest API request Body array - java

I am trying to automate one API using rest API JAVA. I have kept sample request json in one file and before passing that json I want to modify some values. New values are in Map.
For example I want to modify 'company' value to 'Microsoft'(which is in hashmap newInputs). Problem is my code is adding new 'company' at the top of body instead of updating it. How do i update specific values in Items array.
json body in file
{
"Items": [
{
"newValue": "Q3",
"company": "Test",
"oldValue": "Q2",
"Date": "2022-03-27"
}
]
}
What i want to pass to API
{
"Items": [
{
"newValue": "Q3",
"company": "Microsoft",
"oldValue": "Q2",
"Date": "2022-03-27"
}
]
}
What my code is passing
{
"company": "Microsoft",
"Items": [
{
"newValue": "Q3",
"company": "Test",
"oldValue": "Q2",
"Date": "2022-03-27"
}
]
}
My code
public static String createItem(Map<String, String> newInputs) {
JSONArray jsonArray = null;
JSONObject jsonObject;
try {
jsonArray = new JSONArray(new String(
Files.readAllBytes(Paths.get("src", "test", "resources", "Payloads", "testdata.json"))));
jsonObject = new JSONObject(jsonArray.get(0).toString());
for (String key : newInputs.keySet()) {
jsonObject.put(key, newInputs.get(key));
}
jsonArray.put(0, jsonObject);
}

Related

Extract data from YouTube Data API with Java / Sprint Boot

I am trying to extract title, videoId, and description data of all the videos I got from using YT Data API. I was able to return the data in what looks like JSON format (but it is actually LinkedHashMap when I check with getClass()) in Postman and Chrome browser, but was unable to extract the value from specific keys I have mentioned above.
I tried:
System.out.println((rest.getForObject(url, Object.class, params)).get("items"));
It asks me to cast to JSONObject
Overall, I need to extract the data and convert into xml before sending it over to ActiveMQ
Edit:
Format I get in Postman/Chrome browser
{
"kind": "youtube#searchListResponse",
"etag": "3LV4enCWAzOaiqJb_cMIUVklXJY",
"nextPageToken": "CAUQAA",
"regionCode": "CA",
"pageInfo": {
"totalResults": 478712,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "gt6x7J2XpzU8Mpb3yv9_HmNTzWY",
"id": {
"kind": "youtube#video",
"videoId": "I_ZK0t9-llo"
},
"snippet": {
"publishedAt": "2021-03-01T18:15:13Z",
"channelId": "UC2WHjPDvbE6O328n17ZGcfg",
"title": "Stack Overflow is full of idiots.",
"description": "The Stack Overflow culture needs to be fixed. The overall gatekeeping & elitism in computer science & programming - as a whole ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/I_ZK0t9-llo/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "ForrestKnight",
"liveBroadcastContent": "none",
"publishTime": "2021-03-01T18:15:13Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "RwmGP1qMzUCzK6oV82s0NUEOETw",
"id": {
"kind": "youtube#video",
"videoId": "sMIslcynm0Q"
},
"snippet": {
"publishedAt": "2021-03-07T16:00:13Z",
"channelId": "UCXwjZTvpFiBl93ACCUh1NXQ",
"title": "How To Use Stack Overflow (no, ForrestKnight, it's not full of idiots)",
"description": "Hey everyone, I can't believe I have to make this video. Unfortunately ForrestKnight recently made a video saying Stack Overflow ...",
"thumbnails": {
...
Edit2: I tried
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
JSONArray array = jsonObject.getJSONArray("items" );
for(int i=0;i<array.length();i++){
JSONObject snippet =array.getJSONObject(i);
System.out.println(snippet.getJSONObject("snippet").get("title"));
}
JSONObject["items"] not found.
Edit3:
I also tried without Edit2 and just
JSONObject jsonObject = new JSONObject( rest.getForObject(url, Object.class, params));
System.out.println(jsonObject);
No error and I was about to fetch data shown in Postman. But in console printed {}, meaning I might not have gotten the data and won't be able to extract.
I tried extracting using .get System.out.println(jsonObject.get("items"));
and I got the same error JSONObject["items"] not found.
Seems like it could be a format error, again it looks like json already and to use .get, I placed it inside jsonObject but found nothing
Edit4: I can confirm the data I get back is Json (like it says on the doc) using
try {
new JSONObject(rest.getForObject(url, Object.class, params));
} catch (JSONException ex) {
// edited, to include #Arthur's comment
// e.g. in case JSONArray is valid as well...
try {
new JSONArray(rest.getForObject(url, Object.class, params));
} catch (JSONException ex1) {
return false;
}
}
return true;
Returned true
Edit5: Seems like the keys is null after trying
String[] keys = JSONObject.getNames(jsonObject);
// iterate over them
for (String key1 : keys) {
// retrieve the values
Object value = jsonObject.get(key1);
// if you just have strings:
String value1 = (String) jsonObject.get(key1);
System.out.println(value);
System.out.println(value1);
}
Cannot read the array length because "keys" is null
The RestTemplate delegates to the underlying Jackson to deserialize the JSON string to a java object .If you get the HTTP response as a generic object type , it will deserialize it into a Map.
You can simply create a POJO with the structure that is the same as the expected JSON response, and then use the Jackson annotations to configure how to deserialize the JSON into this POJO , and get the HTTP response as this POJO class.
Something like :
public class Result {
#JsonProperty("items")
private List<Item> items = new ArrayList<>();
}
public class Item {
#JsonProperty("kind")
private String kind;
#JsonProperty("etag")
private String etag;
#JsonProperty("snippet")
private List<Snippet> snippets = new ArrayList<>();
}
public class Snippet {
#JsonProperty("channelId")
private String channelId;
#JsonProperty("title")
private String title;
}
Then use the following to get the response :
Result result = rest.getForObject(url, Result.class, params);
Once you get the Result POJO , use the favourite library to serialize it into XML.
P.S I just show you the ideas. You have to fine tune the POJO structure

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

get a value from a json object (Google map distance)

hello I'm trying t get the distance from a JSON object
{
"destination_addresses": [
"Rabat, Morocco"
],
"origin_addresses": [
"Marrakesh, Morocco"
],
"rows": [
{
"elements": [
{
"distance": {
"text": "324 km",
"value": 323624
},
"duration": {
"text": "3 hours 24 mins",
"value": 12233
},
"status": "OK"
}
]
}
],
"status": "OK"
}
I succeeded to get the elements object but I can't get the distance
org.json.JSONException: No value for distance
at org.json.JSONObject.get(JSONObject.java:389)
at com.application.zarbagaskazay.colivoiturage.testMApsActivity$1.onResponse(testMApsActivity.java:66)
at com.application.zarbagaskazay.colivoiturage.testMApsActivity$1.onResponse(testMApsActivity.java:56)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
here is the code
public void onResponse(JSONObject response) {
try {
JSONArray rows = response.getJSONArray("rows");
JSONObject elements=rows.getJSONObject(0);
// JSONObject cc= elements.getJSONObject("distance");
System.out.println(elements.get("distance"));
button.setText(elements.get("distance").toString());
} catch (JSONException e) {
e.printStackTrace();
}
In my suggestion:
You can replace
System.out.println(elements.get("distance"));
with
System.out.println(elements.getJSONArray("elements").getJSONObject(0).getJSONObj
ect("distance"));
Above sop will print/extract "distance" json value.
{"text":"324 km","value":323624}
Hope it works at your end too!
JSONObject jsonObject = new JSONObject("YOUR RESPONSE STRING");
JSONArray jsonArray = jsonObject.getJsonArray("rows");
JSONArray jsonArray_elements =jsonArray.getJsonObject(0).getJsonArray("elements");
JSONObject jsonObject_distance =
jsonArray_elements.get(0).getJsonObject("distance");
String text = jsonObject_distance.getString("text");
String value = jsonObject_distance.getString("value");

JSONObject is not getting converted to String properly

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.

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();
}
}

Categories