IN json object if we can found if data exist by jsonobj.has("element_name") by how can we check that data is jsonarray or json object, follow error gives error if only one events element found and throws JSONexception.
JsonObject jObj;
if (json.has("Events")) {
try {
JSONArray eventsArray = json.getJSONObject("Events");
} catch (JSONException e) {
jObj = json.getJsonObject(""Events"")
}
}
Is there a reason you're trying to read an array using getJSONObject instead of getJSONArray?
If it's possible that the Events array doesn't always exist, you should be using the optJSONArray method.
If it's a different problem, you'd need to post some example JSON for the success and failure cases to make your question clearer.
Related
I'm having a problem in reading the "Email" field from a JSON file, using Java. When I try to read it, it only reads the first one, even if I put more than one, I tried different things but nothing seems to go. Any way to solve it?
Here is the code:
This is the sign in method, where I write every data about the customer on the JSON file
JSONObject customer = new JSONObject();
JSONArray list = new JSONArray();
customer.put("Email", emailCliente.getText());
customer.put("Tipo", "Cliente");
customer.put("Name", nomeCliente.getText());
customer.put("Surname", cognomeCliente.getText());
customer.put("BirthDate", dataNascitaCliente.getText());
customer.put("Address", indirizzoCliente.getText());
customer.put("Phone", telefonoCliente.getText());
customer.put("Password", pswCliente.getText());
list.add(customer);
try {
FileOutputStream file = new FileOutputStream("Db.json", true);
ObjectOutputStream fileWriter = new ObjectOutputStream(file);
fileWriter.writeObject(list);
fileWriter.flush();
fileWriter.close();
}
This is the code for reading from JSON file:
public class Read implements Serializable{
public static void main(String[] args) throws IOException {
try{
FileInputStream reader = new FileInputStream("Db.json");
ObjectInputStream ois = new ObjectInputStream(reader);
Object customer = (Object) ois.readObject();
JSONArray tmp = (JSONArray) (customer);
for(Object obj : tmp) {
JSONObject tmpObj = (JSONObject) obj;
System.out.println(tmpObj.get("Email"));
}
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} }
You're using the org.json library to create and read JSON data.
Don't. That library is deplorably bad.
I know json.org lists it.
An excellent choice is jackson, or perhaps gson if you want an alternative. As #Raúl Garcia mentioned in a comment, here is a good baeldung tutorial on jackson.
NB: DataInputStream and DataOutputStream are for java's serialization mechanism, which isn't JSON and you don't want those in any case, so, throw out your 'read' code and start from scratch, by following the tutorial. Also, your exception code is problematic; exceptions contain 4 bits of info (type, message, trace, and cause); you're throwing out 3 of the 4 useful bits of info then blindly continuing, which likely produces more clutter in your logs, making it extremely difficult to try to figure out what is going wrong. Stop doing this; just 'throws' such exceptions onwards. If you really, really can't, fix your IDE to generate catch (Foo e) {throw new RuntimeException(e);} as a default catch block. NEVER e.printStackTrace();.
You could read it a single line like so when you use unify-jdocs:
Document d = new JDocument(s); // where s is a JSON string
String s = d.getString("$.Email");
unify-jdocs is a library I have created to work with JSON documents. It provides a whole lot of other features as well. Check it out on https://github.com/americanexpress/unify-jdocs
I am using Rest Assured Framework for API testing(Using Java).
At line (1),I am expecting error as there is mismatch in expected JSON response and Actual JSON response
But instead my code is executing successfully.
Can someone please tell me if I am doing anything wrong in below code?
public void test123() {
try {
//Read the Curl Request Input file
String json = input.readFromTextFile(
System.getProperty("user.dir") + "\\src\\test\\resources\\inputFile\\CurlDataFile.txt");
json = json.replaceAll(" ", "");
RestAssured.baseURI = "My URL";
given().
contentType("application/json").
body(json).
when().
post("").
then().
assertThat().body(matchesJsonSchemaInClasspath("testCurlOuput1.json")); (1)
} catch (IOException e) {
e.printStackTrace();
}catch(JsonSchemaValidationException e){
e.printStackTrace();
}
}
This is not directly relevant to REST-assured, but I suggest you take a look at Karate, because IMO it may be exactly what you are looking for.
One of the core features of Karate is that you can perform a full equality match of a JSON payload in one step.
And you can easily use JSON from files, which encourages the re-use of payloads across multiple tests.
You are catching all Exceptions. When your assertThat(..) fails, it throws an Exception. Put a breakpoint on the e.printStackTrace(); run in DEBUG mode and check that your AssertionException/Error isn't being caught.
Instead of catching exceptions, just add all Checked Exceptions to your test signature. If an exception is uncaught, it will fail the test. Alternatively, but less prefered in my opinion, resolve by putting fail(); in the catch block.
Finally I choose different library i.e. jayway.restassured library and then JSON Assert library (org.skyscreamer.jsonassert.JSONAssert) which will comapre actual and expected response.
public void test123() {
String postData = input.readFromTextFile(System.getProperty("user.dir") + "\\src\\test\\resources\\inputFile\\CurlDataFile.txt");
RestAssured.baseURI = "MY URL";
Response r = (Response)given().contentType("application/json").body(postData).when().post("");
String responseBody = r.getBody().asString();
String curlResponse = //I am providing expected Curl response here
//JSON Assertion for matching Expected and Actual response
JSONAssert.assertEquals(curlResponse, responseBody, false);
}
Also sometime we may want to avoid comparing particular field from JSON like some ID field which generate dynamically which we can do using JSON comparator
I am a fan of JSONAssert as this provides easy comparing of complete JSONs.
Just use .extract().response().getBody().asString() to get the string representation of the answer.
Complete example:
#Test
public void getReturnsExpectedDataForMailExampleCom() throws JSONException {
String response = get("/users/mail#example.com")
.then()
.statusCode(200)
.extract().response().getBody().asString();
JSONAssert.assertEquals(
"{\"email\":\"mail#example.com\",\"locale\":\"de-DE\"}",
response,
false);
}
Update The drawback is that the complete JSON is not output to stdout if the assertion fails.
I am a front-end web developer trying to learn more about the back-end. Currently I just want to read in a local JSON file and expose it in a REST service to be parsed by AngularJS (does that make sense?). I believe I have the servlet set up correctly, but am not sure about how I am approaching this from a Java perspective. It's worth noting that I'm a JavaScript programmer. There are two methods that I am trying to decide between.
The following methods are contained in the class
#Path("/")
public class JsonRESTService {
.....
}
First method
#GET
#Path("/jsonService")
#Consumes("application/json")
#Produces("application/json")
public Response jsonREST(InputStream incomingData) {
StringBuilder jsonBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incomingData));
String line = null;
while((line = in.readLine()) != null) {
jsonBuilder.append(line);
}
} catch(Exception e) {
System.out.println("Error Parsing: - ");
}
System.out.println("Data Received: " + jsonBuilder.toString());
return Response.status(200).entity(jsonBuilder.toString()).build();
}
Second Method: not sure what to return.
#GET
#Path("/jsonService")
#Consumes("application/json")
#Produces("application/json")
public Response jsonREST(InputStream incomingData) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("C:/files/flat.json"));
JSONObject jsonObject = (JSONObject) obj;
} catch(Exception e) {
e.printStackTrace();
}
}
web.xml servlet mapping
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
So this should be exposed to http://localhost:8080/myapp/rest/jsonService. I got some of this code from a tutorial, but it seems like I want to have a method that returns a JSONObject instead of a Response. Is that correct? Am I on the right track, or is there a really good example of what I am trying to do that I haven't found yet?
There are multiple ways of doing it. You can try this way in the second method
Change the return type to String and return the value of JSONObject as a String using
return jsonObject.toString();
In the client side, Angular JS services - you can convert the String into JSON object through
var obj = JSON.parse(text);
So, now obj is a JSON object which you can use it for further processing.
if you are a JavaScript developer and getting started quickly is the goal, then I would recommend you checkout
http://www.dropwizard.io/getting-started.html
There are a few advantages here
a) much of the server infrastructure stuff is hidden away
b) you can focus on your implementation details
c) no need to figure out how to deploy this etc, it comes with a server built in.
To answer your question about the return type - the server will return javax.ws.rs.core.Response - or some other variation of a Response object. This encapsulates things like HTTP Status codes http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .
Therefore in order to send a simple response back you may use something like :
return Response.accepted().entity(String.format("{\"JSON\" : \"%s\"}",value)).build();
Replace the string with a JSON string read from file system or generate the JSON from object - what ever your pick of poison is.
I have this JSON data file
[{"entityClass":"DefaultEntityClass","mac":["00:00:00:00:00:02"],"ipv4":[],"vlan":[],"attachmentPoint":[{"switchDPID":"00:00:00:00:00:00:00:02","port":1,"errorStatus":null}],"lastSeen":1398463052792}]
and I want to get the "mac". but I don't know which data type I have to use, since the server
says that it is neither a long nor a string value. Which datatype is this "mac" ?.
my code:
try {
JSONArray arraydevice = new JSONArray(devicesJson);
JSONObject obj = arraydevice.getJSONObject(0);
long mac = obj.getLong("mac");
System.out.println("The mac address of the host is " + mac);
}
catch (JSONException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
Thanks in advance
["00:00:00:00:00:02"]
is an array with one element, and that element is a string.
String mac = obj.getJSONArray("mac").getString(0);
though it would probably be a good idea to check the .length() of the array before you try and get anything out of it, in case it turns out to be empty.
From the JSON Schema the MAC Address looks like an Array of String. However if you have a Class structure defined on the server , you can use that for converting the JSON into an object.
I'm trying to send a JSON object which contains a JSON array with JSON objects inside via HTTP POST parameters.
The format of the parameter (what the server expects) is something like:
{""team"":[
{""teamid"":""179228"",""position"":1},
{""teamid"":""218036"",""position"":2},
{""teamid"":""88109"",""position"":3},
{""teamid"":""88111"",""position"":4},
{""teamid"":""165536"",""position"":5},
{""teamid"":""224645"",""position"":6}
]}
nevertheless, what gets sent is:
{"team":"[
\"{\\\"position\\\":0,\\\"teamid\\\":\\\"88107\\\"}\",\"{\\\"position\\\":1,\\\"teamid\\\":\\\"88109\\\"}\",\"{\\\"position\\\":2,\\\"teamid\\\":\\\"156714\\\"}\",\"{\\\"position\\\":3,\\\"teamid\\\":\\\"138877\\\"}\",\"{\\\"position\\\":4,\\\"teamid\\\":\\\"168730\\\"}\",\"{\\\"position\\\":5,\\\"teamid\\\":\\\"88110\\\"}\",\"{\\\"position\\\":6,\\\"teamid\\\":\\\"88111\\\"}\",\"{\\\"position\\\":7,\\\"teamid\\\":\\\"134431\\\"}\",\"{\\\"position\\\":8,\\\"teamid\\\":\\\"88112\\\"}\",\"{\\\"position\\\":9,\\\"teamid\\\":\\\"138507\\\"}\",\"{\\\"position\\\":10,\\\"teamid\\\":\\\"138880\\\"}\",\"{\\\"position\\\":11,\\\"teamid\\\":\\\"138881\\\"}\",\"{\\\"position\\\":12,\\\"teamid\\\":\\\"151465\\\"}\",\"{\\\"position\\\":13,\\\"teamid\\\":\\\"151464\\\"}\
"]"}
The way I build that JSON object is the following:
JSONArray teamArray = new JSONArray();
JSONObject jsonRoot = new JSONObject();
for (int i = 0; i < mTeams.size(); i++) {
String teamId = null;
BaseModel data = mTeams.get(i);
if (data != null && data instanceof TeamModel) {
teamId = ((TeamModel) data).getId();
}
JSONObject teamObject = new JSONObject();
try {
teamObject.put(
getResources().getString(
R.string.sendResortedTeamsPosition), i);
teamObject.put(
getResources().getString(
R.string.sendResortedTeamsTeamId), teamId);
teamArray.put(teamObject);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
jsonRoot.put("team", teamArray);
mNameValuePairs.put("teams", jsonRoot);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
In the last but one line (jsonRoot.put("team", teamArray);) it has the same format as what gets sent in the last line, but with one less \, so one less times "parsed" apparently.
Part of my HTTP code:
String postBody = json.toString();
Log.d("HTTPHelper", "posting JSON: " + postBody);
((HttpPost) httpRequest).setEntity(new StringEntity(postBody));
Why is this happening? Is it Java?
Any ideas how could I build the correct JSON? or any work around?
Thanks a lot in advance!
I gave this up, and decided to go the dirty-way: replacing chars manually the following way:
json = new JSONObject(nameValuePairs.toString().replace("\"", "'"));
json = new JSONObject(json.toString().replace("\"", ""));
It's ugly, probably dangerous or risky, but it works...
Too much code for this task, checkout this library https://github.com/kodart/Httpzoid
It uses GSON internally and provides API that works with objects. All JSON details are hidden.
Http http = HttpFactory.create(context);
http.get("http://example.com/users")
.handler(new ResponseHandler<User[]>() {
#Override
public void success(User[] users, HttpResponse response) {
}
}).execute();
just a tip... i'm not really into android, just java..
but you could de- and encode your json with Base64 on both sides, and pass the encoded "String".
so you don't have to worry about any "dirty-way" replacing.
hope this helps u or others, too. :)