Not able to access json file content [duplicate] - java

This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 4 years ago.
I am parsing a json file using json parser object. I am not able to access the request structure and it's inner body content.
I've written code like:
private static final String filePath = "D:\\score_api.json";
public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
FileReader reader = new FileReader(filePath);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
System.out.println("++++++++++++++++++\n"+jsonObject);
// prints the whole json content. success!
JSONObject structure = (JSONObject) jsonObject.get("provider");
System.out.println("provider name: " + structure.get("name"));
// prints the provider name. success!
JSONArray req= (JSONArray) jsonObject.get("interactions");
Iterator i = req.iterator();
while (i.hasNext()) {
JSONObject reqObj = (JSONObject) i.next();
System.out.println("description: " + reqObj.get("description") +"\n");
System.out.println("request body: " + reqObj.get("request")); // prints full request body
System.out.println("path: " + reqObj.get("path") +"\n"); // Failing, getting null value.
System.out.println("reponse body: " + reqObj.get("response") +"\n"); // Success
}
}
And it's output:
++++++++++++++++++
{"full json file content prints"}
provider name: SIS
description: API POST Score
request body: {"full request body prints"}
path: null
reponse body: {"status":200}
I am struggling to access request body content. And its child part.
I want to access the value of 'path' and other inner values like 'adptPolVal', 'eEcoId' and Source structure.
I am a newbie to java, m trying but failing.
Any help would appreciated !
Thanks in advance !
Here's my json file content...
{
"consumer": {
"name": "Consumer1"
},
"provider": {
"name": "provider_a"
},
"interactions": [
{
"description": "API Score",
"providerStates": [
{
"name": "",
"params": {}
}
],
"request": {
"method": "post",
"path": "Z123MI6/services/score",
"headers": {
"content-type": "application/json"
},
"body": {
"adptPolVal": true,
"datapoints": [
{
"dataId": " data.point.id ",
"source": {
"srcType": "sourceType.dev.admin",
"snum": "12345",
"instId": "intance id",
"contId": "container id",
"appId": "com.consumer."
},
"userId": "userId",
"ts": 1234567891011,
"lt": 11.12345,
"lng": 123.456,
"ipId": "192.168.1.1",
"geoGraph": ""
}
],
"eEcoId": "ecoId"
}
},
"response": {
"status": 200
}
}
]
}

Try replacing this line
JSONArray req= (JSONArray) jsonObject.get("interactions");
With :
JSONArray req= (JSONArray)jsonObject.getJSONArray("interactions");

You can use following class as a reference to get your desired value.
Please make sure to use getJSONArray() and getJSONObject() method
appropriately according to your output.
package com.test.test;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class Test {
public static void main(String[] args) throws IOException, JSONException {
String filePath = "C://Users//hello//Desktop//New Text Document.txt";
String string = FileUtils.readFileToString(new File(filePath));
JSONObject jsonObject = new JSONObject(string);
JSONArray jsonArray = jsonObject.getJSONArray("interactions");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject reqObj = jsonArray.getJSONObject(i);
System.out.println("description: " + reqObj.get("description") +"\n");
System.out.println("request body: " + reqObj.get("request")); // prints full request body
System.out.println("reponse body: " + reqObj.get("response") +"\n"); // Success
JSONObject requestBoday = reqObj.getJSONObject("request");
JSONObject body = requestBoday.getJSONObject("body");
}
}
}

Related

Updating JSON Key within Json File

I have the following code to update the key "runTimeDate" within my json file.
`final LocalDate plus180Days = LocalDate.now().plusDays(180);
DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
String substituteDate = plus180Days.format(dateTimeFormatter);
String jsonFile = "src/examples/sample.json";
public String Body_ValueDate()
{
return jsonFile.replaceAll("\"runTimeDate\"", "\"" + substituteDate +
"\"");
}
public String Body_KeyDate()
{
return Body_ValueDate().replaceAll("\"keyDate\"", "\"" +
substituteDate + "\"");
}`
I used the code above from here: https://stackoverflow.com/questions/7463414/what-s-the-best-way-to-load-a-jsonobject-from-a-json-text-file#:~:text=23-,With%20java%208,-you%20can%20try
Thing is, the date is not getting updated. plus180Days is basically a function adding 180 days from current date. Can anyone share what I am missing here?
final LocalDate plus180Days = LocalDate.now().plusDays(180);
Sample Json
{
"city": {
"details": {
"a1": "AUS",
"a2": "AUS",
"country": "AUS"
}
},
"detail": {
"getCountryDetail": {
"b1": "SYD",
"b2": "MEL",
"country": {
"keyDate|AUS|1234|SYD|MEL": {
"date1": "runTimeDate",
"time1": "15:38",
"date2": "runTimeDate",
"time2": "19:13"
},
"keyDate|AUS|1234|ADL|MEL": {
"date1": "runTimeDate",
"time1": "15:38",
"date2": "runTimeDate",
"time2": "19:13"
}
}
}
}
}
I am using the updated json method "Body_KeyDate" as body parameter for my rest assured method as per here:
#Test
public void UA_Avail_Cascading_Request()
throws IOException
{
Response response = RestAssured.given()
.header(readConfigFile())
.contentType("application/json")
.body(Body_KeyDate())
.when()
.post(readBaseUrl() + "samplePage")
.then().statusCode(200)
.log().all()
.extract().response();
}
Following solution worked: with ObjectMapper
public JsonNode RequestBody_DynamicDate() throws Exception
{
String requestBodyJson = loadJson("Sample.json");
String removeKeyDate = requestBodyJson.replace("keyDate", NEW_DATE);
String removeValueDate = removeKeyDate.replace("runTimeDate", NEW_DATE);
JsonNode processedNewDates = OBJECT_MAPPER.readTree(removeValueDate);
System.out.println("New JSON Body: "
+ OBJECT_MAPPER
.writerWithDefaultPrettyPrinter()
.writeValueAsString(processedNewDates));
return processedNewDates;
}
Here is the code for loadJson: BASEPATH is the folder location
String loadJson(String filePath)
{
try
{
return new String(Files.readAllBytes(Paths.get(BASEPATH + filePath)));
}
catch (Exception e)
{
Assertions.fail("unable to load test data, check file path, and format");
throw new RuntimeException();
}
Hope this helps someone. Also turns there was some restrictions and limitations on which library and packages can be used.

Gson howto parse different data types in a single array?

I have an API response that includes METAR weather data as well as string error responses, both contained in the same "data" array. I am using Gson to parse the json response on Android. This works great until I get a string error response. I've tried my hand at trying to write a custom Gson deserializer with no luck. Can someone give me a working example or point me in the correct direction on how to handle this?
The response looks like this:
{
"results": 4,
"data": [
{
"icao": "KAJO",
"name": "Corona Municipal",
"observed": "05-11-2018 # 18:56Z",
"raw_text": "KAJO 051856Z AUTO VRB03KT 10SM CLR 23/08 A2989 RMK AO2 SLP129 T02330078 $",
"barometer": {
"hg": 29.890000000000001,
"kpa": 101.22,
"mb": 1012.9
},
"clouds": [
{
"code": "CLR",
"text": "Clear skies",
"base_feet_agl": 0,
"base_meters_agl": 0
}
],
"dewpoint": {
"celsius": 8,
"fahrenheit": 46
},
"elevation": {
"feet": 535,
"meters": 163
},
"flight_category": "VFR",
"humidity_percent": 38,
"temperature": {
"celsius": 23,
"fahrenheit": 73
},
"visibility": {
"miles": "10",
"meters": "16,093"
},
"wind": {
"degrees": 0,
"speed_kts": 3,
"speed_mph": 3,
"speed_mps": 2
}
},
"KGNG METAR Currently Unavailable",
"CXCY Invalid Station ICAO"
]
}
As you can see the "data" array may return a metar object (I have this part working) or an unnamed error string. It is when I get the error string returned that my parsing fails.
As a test I wrote the following. But it is also not working. How can I parse the both the raw unnamed string and the metar object?
import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.List;
public class Main {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Response.class, new MyDeserializer())
.registerTypeAdapter(String.class, new String())
.create();
Response response = gson.fromJson(str_json, Response.class);
System.out.println("Hello World!");
}
static class MyDeserializer implements JsonDeserializer<Response> {
#Override
public Response deserialize(JsonElement json, Type typeOfT
,JsonDeserializationContext context) throws JsonParseException {
// Get the "data" element from the parsed json
JsonElement data = json.getAsJsonObject().get("data ");
// Deserialize it. You use a new instance of Gson to avoid
// infinite recursion
return new Gson().fromJson(data, Response.class);
}
}
/*===============================
* Data Definitions
*==============================*/
class Response {
public String results;
public List<Station> Stations;
}
class Station {
public String name;
public String icao;
}
public static String str_json = "{\n" +
" \"results\": 3,\n" +
" \"data\": [\n" +
" {\n" +
" \"name\": \"Billings Logan Intl\"," +
" \"icao\":\"KBIL\"," +
" },\n" +
" \"CYPG METAR Currently Unavailable\",\n" +
" \"KGNG METAR Currently Unavailable\"\n" +
" ]\n" +
"}";
}
First it would make thing seasier if you changed the DTOs a bit, for the Response
public class Response {
public String results;
public List<Station> data; // it is named data in JSON not Stations
}
Then the rest is done depending on how you would like to handle the error text. One easy way would be to just add error field to your Station so that it would be:
public class Station {
public String name;
public String icao;
public String error; // used if there is only error string
}
With a custom deserialiser like:
public class StationDeserializer implements JsonDeserializer<Station> {
private final Gson gson = new Gson();
#Override
public Station deserialize(JsonElement json, Type typeOfT
,JsonDeserializationContext context)
throws JsonParseException {
try {
return gson.fromJson(json, Station.class);
} catch (JsonSyntaxException e) {
// it was not a Station object
Station station = new Station();
// so try to set the error string
station.error = json.getAsString();
return station;
}
}
}
The try to deserialize:
Response response = new GsonBuilder()
.registerTypeAdapter(Station.class, new StationDeserializer())
.create()
.fromJson(str_json, Response.class);
Checking if there is an error string in a Station or not you can see if the data is valid.

How to Parse Json Objects of Json Object and of Object (outdated) [duplicate]

This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 5 years ago.
I'm trying to parse multiple objects,Bellow i'm receiving Json Sample The requirement completed and my question now outdated, can someone please up-vote to help me for asking next question? Will he helpfull for and thanks for
{
"0": //outer objects are multiples, i just post one object for sample
{
"id": "1",
"name": "B2 MR1",
"description":
{
"0": //it is also multiple objects m just showing one
{
"title": "Carve the Future",
"description": "Welcome to Meeting Room 1",
"push_notification": "Carve the Future",
}
}
},//after that the next obj will be show
.
.
}
In second object 1 i also have above keys and values, i can't handel it, here is my Model.
public class JsonModel {
private String id; //getter setter
private String name; //getter setter
List<InnerDescprtion> description; //getter setter
}
Here is my InnerDescprtion Model
private class InnerDescprtion {
private String id; //getter setter
private String title; //getter setter
}
And below is my java code for parsing it using Gson,
JsonModel outterModelClass= null;
List<JsonModel> listObj = new ArrayList<>();
for (int i = 0; i < responseJson.length(); i++) {
try {
outterModelClass= new Gson().fromJson(responseJson.getString(String.valueOf(i)), JsonModel.class);
listObj.add(outterModelClass); //here i'm getting exception,,
} catch (JSONException e) {
e.printStackTrace();
}
}
I get the solution, Please up-vote to help me.
If it is possible for you I would change the json to something like this:
[{
"id": "1",
"name": "B2 MR1",
"description": [{
"id" : "1-1",
"title": "Carve the Future",
"description": "Welcome to Meeting Room 1",
"push_notification": "Carve the Future"
}]
},
{
"id": "2",
"name": "B2 MR2",
"description": [{
"id" : "2-1",
"title": "Carve the Future 2",
"description": "Welcome to Meeting Room 2",
"push_notification": "Carve the Future 2"
}]
}
]
Then your approach should work with just a few changes:
BufferedReader br = new BufferedReader(new FileReader("c:/test/test.json"));
Type listType = new TypeToken<ArrayList<JsonModel>>(){}.getType();
List<JsonModel> outterModels = new Gson().fromJson(br, listType);
If you can't change the json I would suggest to use another JSON library like json simple and extract everything manually.
Your 'listObj' should be defined this way:
ArrayList<JsonModel> listObj = new ArrayList<JsonModel>();
Well that is a nasty looking JSON. However I recommend you use volley android library. I had a task with somewhat similar problem. Only there was a single object inside of another object. To include volley in your project, update your build.gradle app module with compile 'com.android.volley:volley:1.0.0' inside dependencies{}. baseUrl is the url where you are fetching the JSON from.
Then you can do something like:
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
baseUrl,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
// Parsing json object response
// response will be a json object
for (int i=0; i<response.length(); i++){
JSONObject obj = response.getJSONObject(i);
//id
//name
try{
for (int j=0; j<obj.length() ; j++) {
JSONObject description = obj.getJSONObject(j);
//title
//description
//push notification
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
hidepDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.d(TAG,"Error: "+ volleyError.getMessage() );
Toast.makeText(getApplicationContext(), volleyError.getMessage(), Toast.LENGTH_SHORT).show();
hidepDialog();
}
});
//adding request to request queue
AppController.getmInstance().addToRequestQueue(jsonObjReq);
Add this in your parseJSON(){} method or whatever you've named it.
I have not tried doing what you are trying do to. But it seems doable, with the use of volley library.

Error Unexpected Char javax.json

I am trying to read this JSON code
{
"metadata": {
"clientTransactionId": "",
"serverTransactionId": "20160621101521362-domainrobot-demo.routing-18997-0"
},
"responses": [
{
"domainName": "test.la",
"domainNameUnicode": "test.la",
"domainSuffix": "la",
"earlyAccessStart": null,
"extension": "la",
"generalAvailabilityStart": "2000-01-01T00:00:00Z",
"landrushStart": null,
"launchPhase": "generalAvailability",
"registrarTag": null,
"status": "registered",
"sunriseStart": null,
"transferMethod": "authInfo"
}
],
"status": "success",
"warnings": []
}
With my Java Program:
import javax.json.*;
import java.nio.charset.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.io.*;
public class Main {
public static String readFile(String path, Charset encoding) throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
public static void main(String[] args) throws IOException {
String jsonData = readFile("/home/maltepraktikant/workspace/DomainCreator/bin/JsonData.txt", StandardCharsets.UTF_8);
JsonReader jsonreader = Json.createReader(new StringReader(jsonData));
JsonObject object = jsonreader.readObject();
System.out.println(object);
jsonreader.close();
}
}
I have tried different things, but I haven't found a solution yet. It just gives me the error:
Exception in thread "main" javax.json.stream.JsonParsingException: Unexpected char 65.279 at (line no=1, column no=1, offset=0)
at org.glassfish.json.JsonTokenizer.unexpectedChar(JsonTokenizer.java:532)
at org.glassfish.json.JsonTokenizer.nextToken(JsonTokenizer.java:415)
at org.glassfish.json.JsonParserImpl$NoneContext.getNextEvent(JsonParserImpl.java:222)
at org.glassfish.json.JsonParserImpl$StateIterator.next(JsonParserImpl.java:172)
at org.glassfish.json.JsonParserImpl.next(JsonParserImpl.java:149)
at org.glassfish.json.JsonReaderImpl.readObject(JsonReaderImpl.java:101)
at Main.main(Main.java:19)
Has anyone some ideas?
Get the json response and replace all new lines first before parsing it to object.
response.replaceAll("\r?\n", "");
Sample code using GSON API
String json = "{\"msg\" : \"Hello \n World\"}";
System.out.println(json);
json = json.replaceAll("\r?\n", "");
Map<String, String> map = new Gson().fromJson(json, new TypeToken<Map<String, String>>(){}.getType());
System.out.println("Actual message:" + map.get("msg"));
Output:
{"msg" : " Hello
World"}
Actual message: Hello World
In my case error was due to missing quotes for values or key. In the json string null values are not in quotes (ex: "earlyAccessStart": null). Keeping them in quotes would solve the issue.
Note: Validate the json string once through a valitor like

Error java.lang.NullPointerException in JSON parsing

I am new to Java,and using below code to parse JSON,but I am getting java.lang.NullPointerException error when the offers {} node is coming with empty values ,which is public class in my code.
How to handle empty JSON nodes/keys ??
The code is able to parse JSON if there is data under "offers" like "info",but exiting with NULL exception error when JSON returns and empty as shown below.
ERROR MSG :
Exception in thread "api_temp_1.dat" java.lang.NullPointerException
at com.t.dw.dl.api.data.Pkg_Data.getCount(Pkg_Data.java:57)
at com.t.dw.dl.api.DataRetrieveRunnable.run(DataRetrieveRunnable.java:185)
Code extracts from error lines shown
public long getCount() {
if (offers != null)
return offers.getPkg().size();
return 0;
}
**Code from com.t.dw.dl.api.DataRetrieveRunnable.run(DataRetrieveRunnable.java:185)**
try
{
Pkg_Data dls = parseResult(result);
if (dls.getCount() > 0)
{
fw.write(deals.writeResults(fields, delimiter));
threadStats.increment(Stats2.COUNT_OF_ROWS_PROCESSED,
dls.getCount());
}
}
Parsing code:
private Pkg_Data parseResult( String result ) throws JsonParseException {
JsonParser parser = new JsonParser();
JsonElement jo = parser.parse(result);
Gson gson = new Gson();
Pkg_Data ehw = gson.fromJson(jo, Pkg_Data.class);
return ehw;
}
CODE:
import java.util.ArrayList;
public class offers
{
private ArrayList<PkgData> pkg;
class Pkgdata
{
Info Info;
class Info
{
String Id;
String Url;
}
public String getId() {
if (Info != null && Info.Id != null)
return Info.Id;
return "";
}
SAMPLE JSON: NOT working for this where "offers" returns empty
{
"offerInfo":{
"siteID":"1",
"language":"en_US",
"currency":"USD"
},
"offers":{ }
}
That is because offer is compared to the Class that you giving to refer so in that case Json will be wrong try with this Json it will work.
{
"offerInfo": {
"siteID": "1",
"language": "en_US",
"currency": "USD"
},
"offers": {
"siteID": " ",
"language": "",
"currency": " "
}
}
Because Compiler not able to find any field attribute in side your offer object so its giving error.
try this Json.

Categories