I am fetching a JSONObject "result" from the following JSONObject:
{
"success" : true,
"message" : "",
"result" : {
"uuid" : "e606d53c-8d70-11e3-94b5-425861b86ab6"
}
}
I am using this code:
CloseableHttpClient httpclient = HttpClients.createDefault();
String url = "some url";
HttpGet httpget20 = new HttpGet(url);
httpget20.setHeader("apisign",buildHmacSignature(url, apisecret));
try ( CloseableHttpResponse response2 = httpclient.execute(httpget20)){
HttpEntity entity = response2.getEntity();
JSONObject obj2 = new JSONObject(EntityUtils.toString(entity));
JSONObject result = obj2.getJSONObject("result");
obj2 is the whole json object including "success", "message" and "result".
However, this line of code generates the following error message:
Exception in thread "AWT-EventQueue-0" org.json.JSONException: JSONObject["result"] is not a JSONObject.
I am not sure how a JSONObject can not be a JSONObject. Can someone explain the problem here?
JSONObject.getJSONObject can return a JSONObject only. It will not return boolean, long or String, and it will not return JSONObject.NULL in particular, because that is not a JSONObject itself (it says Java Object in the docs, and has a specific private type in the implementation).
Use isNull for checking it beforehand or just accept that it throws an exception and prepare for it. Of course you can also use the generic get and check the result against JSONObject.NULL afterwards, perhaps use instanceof, just none of these will make the code simpler and all of them will introduce casting/casting attempts at some point.
I was linking the Android docs for readability, but you can of course dig into source code too, like getJSONObject. You can find the NULL at the beginning of the same file if you are interested.
Related
I am learning JavaEE, I have a JSONObject, and I need to retrieve a nested propriety "link", that is a URL to a PDF file (inside the JSON). Everything I try gives me error. Any hints or help would be appreciated.
The JSON: https://kalilcamera.com.br/teste.json (i want the URL http://www.africau.edu/images/default/sample.pdf inside this JSON)
My parse (working):
JSONObject testJson = new JSONObject( HttpUtil.send("POST", "https://kalilcamera.com.br/teste.json", "s", null).getResponseMessage());
My try to get the Link:
String urlPrescricaoMemedPDF = testJson.get("link").toString();
no matter what i try, gives me error.
my code from the debug perspective (Easy to undersand):
https://i.stack.imgur.com/584LR.png
Thanks for any help.
First you have to go through your json to get to the part where you can call get. Think of it as an nested Map, if you call get for something that is 3 layers down, you wont get anything usefull.
Second use getAsString instead of toString
final HttpRequest get = HttpRequest.newBuilder(URI.create("https://kalilcamera.com.br/teste.json"))
.GET()
.build();
final HttpClient httpClient = HttpClient.newHttpClient();
final HttpResponse<String> response = httpClient.send(get, HttpResponse.BodyHandlers.ofString());
final JsonObject bodyJson = JsonParser.parseString(response.body()).getAsJsonObject();
final JsonElement data = bodyJson.get("data");
final JsonElement zero = data.getAsJsonArray().get(0);
final JsonElement attributes = zero.getAsJsonObject().get("attributes");
final JsonElement link = attributes.getAsJsonObject().get("link");
System.out.println(link.getAsString());
prints : http://www.africau.edu/images/default/sample.pdf
Use object.getString("link") instead of get("link").
I am getting response with okhttp library android java from a url and i converted that response to string.below is response string :
Here is the response string :
"{\"data\":{\"refrenceCode\":\"upfF+kMKv4Q=\",\"identityTypeId\":\"NV25GlPuOnQ=\",\"idNumber\":\"1000\",\"dateOfBirth\":19961004,\"registrationDate\":\"2020-05-12T12:03:47.647\",\"mobile\":\"0022343 \",\"regionId\":\"NV25GlPuOnQ=\",\"cityId\":\"NV25GlPuOnQ=\",\"carTypeId\":\"NV25GlPuOnQ=\",\"carNumber\":\"aa 000\"},\"status\":true,\"errorCodes\":[]}"
and when i tried to convert that string to json objectwith below method;
JSONObject jsonobj = new JSONObject(responsestring);
I got following json exception :
org.json.JSONException: Value {"data":{"refrenceCode":"upfF+kMKv4Q=","identityTypeId":"NV25GlPuOnQ=","idNumber":"1000","dateOfBirth":19961004,"registrationDate":"2020-05-12T12:03:47.647","mobile":"0022343 ","regionId":"NV25GlPuOnQ=","cityId":"NV25GlPuOnQ=","carTypeId":"NV25GlPuOnQ=","carNumber":"aa 000"},"status":true,"errorCodes":[]} of type java.lang.String cannot be converted to JSONObject
How it can be fixed?
Here is a solution based on the collective work in the comments:
responsestring = responsestring.substring(1, responsestring.length - 1).replace("\\\"", "\"");
Thanks for #chrylis-onstrike- observation, it helped.
I fixed it by removing first and last " and then replacing \ like below
responsestring = responsestring.replace("\","");
I have recently moved to test API's for a new project with Rest Assured. I am not so fluent in Java, so that is why I need to know how to optimise the code.
Let's say I have an API, which output's JSON in this format -
{
"records":[
0: {
"id" : 1232,
"attribute1": "some_value",
"attribute2": "some_value1"
},
1: {
"id" : 1233,
"attribute1": "some_new_value",
"attribute2": "some_new_value1"
}]}
There are around 400 such objects coming inside the records array. I want to get the id of all the 400 records, and store in an array. I am able to do so, but I think the approach can be optimised.
My current code :
private static Response response;
Response r;
JSONParser parser = new JSONParser();
String resp = response.asString();
JSONObject json = (JSONObject) parser.parse(resp);
JSONArray records= ((JSONArray)json.get("records"));
ArrayList<Long> idlist = new ArrayList<Long>();
for(int i=0;i<records.size();i++) {
idlist.add((Long) ((JSONObject)records.get(i)).get("id"));
}
How can I minimize the lines of code to achieve the same thing?
Response response
// Code that assigns the response
List<Long> idList = response.jsonPath().getList("records.id");
// Code that uses the id list.
I tried to send POST request with some parameters. For this I form MultivaluedMap
if I make this adding to MultivaluedMap
String ban = subscriber.getBan();
String username = user.getUsername();
postData.add("agent", username);
postData.add("datasource", "online");
postData.add("accountId", ban);
String json = RESTUtil.doPost(url, postData);
All work fine
but if I make this
postData.add("agent", user.getUsername());
postData.add("datasource", "online");
postData.add("accountId", subscriber.getBan());
String json = RESTUtil.doPost(url, postData);
I have error:
com.sun.jersey.api.client.ClientHandlerException: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.List
It is my post method
public static String doPost(String url, MultivaluedMap formData) {
try {
Client client = Client.create();
WebResource wr = client.resource(url);
client.setConnectTimeout(CONNECTION_TIMEOUT);
client.setReadTimeout(READ_TIMEOUT);
ClientResponse response2 = wr
.accept("application/json;")
.type("application/x-www-form-urlencoded; charset=UTF-8")
.post(ClientResponse.class, formData);
if (response2.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response2.getStatus());
}
return response2.getEntity(String.class);
} catch (Exception e) {
LOG.log(Level.WARNING, "callRestUrl:", e);
JsonObject jo = new JsonObject();
jo.addProperty("resultCode", "EXCEPTION");
jo.addProperty("details", e.getMessage());
return GSON.toJson(jo);
}
}
And in second case I get error after .post(ClientResponse.class, formData);
I do not understand what is wrong. subscriber.getBan() and user.getUsername() return String like ban and username, but if I use the getter, a have error.
And part 2. I found this article this article
but I do not understand when to use add or put and their difference?
Can you explicit how you create your instance of MultivaluedMap? How are you using it?
MultivaluedMap is a couple of key (single value) and value (list of objects). See the declaration:
public interface MultivaluedMap<K,V> extends Map<K,List<V>>
I suppose both of your snippets are used sequentially in the same piece of code. I the first case, you initialise the value for the key 'ban' (that's mean: the value is a list of one element), in the second case, you add a value to the list to the same key 'ban'. It happens exactly the same for the key 'username'.
I your first case, Java automatically catch the list (of one value) to a string, after the second add, this cannot be the case.
To verify it, you can simply change the order (do first your second case, then the first one). You should get the same error, after the second.
To resolve your case, consider using the method putSingle instead of add if you want to "update/replace" the value, or re-initiate your instance of formData (formData = new ...) before using it another time.
I am hitting a wall trying to get data loaded in a JSON array successfully passed to a java class that runs over the Neo4j server. My intent is to pass a list of entries from the client side to the server - nothing special here. What I am doing is reading the entries on the client side, loading those entries into JSON objects and then putting each JSON object into a JSON array which is then to be passed to the server for further processing.
Here is a section of the client side code that loads the json object and array. NOTE: the below is
just the json related code stripped down w/o the try/catch and other items resident in the code.
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put("field1", field1Value1);
jsonObject.put("field2", field2Value1);
jsonObject.put("field3", field3Value1);
jsonArray.put(jsonObject);
JSONObject jsonObject = new JSONObject();
jsonObject.put("field1", field1Value2);
jsonObject.put("field2", field2Value2);
jsonObject.put("field3", field3Value2);
jsonArray.put(jsonObject);
Here is the client side code that handles the http post part of the equation - I believe this is ok.
StringEntity stringEntity = new StringEntity(jsonArray.toString());
stringEntity.setContentType("application/json");
HttpPost post = new HttpPost(
"http://"server":7474/db/data/ext/serverSideClass/graphdb/processJSONData");
post.setEntity(stringEntity);
HTTPPostResponseResults httpResponse = new HTTPPostResponseResults();
httpResponse.checkResponse(post);
Here is the method interface to the server side code and this is where I believe my problem lies. I am thinking the parameter type needs to something other than JSONArray but am not sure what.
#Name("processJSONData")
#Description("process the data passed in.")
#PluginTarget(GraphDatabaseService.class)
public String processJSONData(#Source GraphDatabaseService graphDb,
#Parameter(name = "jsonArray") JSONArray jsonArray) {
And... here is the error being thrown.
"message" : "java.util.ArrayList cannot be cast to java.util.Map",
"exception" : "BadInputException",
"fullname" : "org.neo4j.server.rest.repr.BadInputException",
"stacktrace" : [ "org.neo4j.server.rest.repr.formats.JsonFormat.readMap(JsonFormat.java:92)",
"org.neo4j.server.rest.repr.RepresentationFormat.readParameterList(RepresentationFormat.java:97)",
"org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension
The above should cover it for the items related to this posting. If there is anything needed to clarify this please let me know and I'll provide it. Thank you in advance.