JSON jsonObject.optString() returns String "null" - java

I'm developing an Android App which uses JSON for the server communication and I've got a weird problem when I'm trying to parse my json file.
This is my json from the server
{
"street2": null,
"province": null,
"street1": null,
"postalCode": null,
"country": null,
"city": null
}
I'm getting the value for City by calling String city = address.optString("city", "") on my address Json-object. For this situation I'm expecting cityto be empty (that's what optString is here for isn't it?) but in fact it contains the String "null". So further null- or isEmpty-checks will return false as the String contains text. If I call address.isNull("city") it returns true which is correct. Only optString fails.
I couldn't find anything on Google or Stackoverflow for this problem. I don't really understand how it can happen as I thought optString would do exactly what I expected. Anybody knows what's going wrong here?

You're not alone in running into this problem and scratching your head, thinking "Could they really have meant this?" According to an AOSP issue, the Google engineers did consider this a bug, but they had to be compatible with the org.json implementation, even bug-compatible.
If you think about it, it makes sense, because if the same code which uses the same libraries run in other Java environments behaves differently in Android, there would be major compatibility problems when using 3rd party libraries. Even if the intentions were good and it truly fixed bugs, it would open up a whole new can of worms.
According to the AOSP issue:
The behavior is intentional; we went out of our way to be bug-compatible with org.json. Now that that's fixed, it's unclear whether we should fix our code as well. Applications may have come to rely on this buggy behavior.
If this is causing you grief, I recommend you workaround by using a different mechanism to test for null, such as json.isNull().
Here's a simple method to help you out:
/** Return the value mapped by the given key, or {#code null} if not present or null. */
public static String optString(JSONObject json, String key)
{
// http://code.google.com/p/android/issues/detail?id=13830
if (json.isNull(key))
return null;
else
return json.optString(key, null);
}

You basically have 2 choices:
1) Send a JSON payload with null values
{
"street2": "s2",
"province": "p1",
"street1": null,
"postalCode": null,
"country": null,
"city": null
}
You will have to check for null values and parse them accordingly:
private String optString_1(final JSONObject json, final String key) {
return json.isNull(key) ? null : json.optString(key);
}
2) Do not send the keys with null values and use optString(key, null) directly (should save you bandwidth).
{
"street2": "s2",
"province": "p1"
}

Got rid off this situation by simply replacing "null" with "".
String city = address.optString("city").replace("null", "");

Using Matt Quigley's answer as a basis, here is the code if you desire to mimic the full functionality of optString, including the fallback portion, written in Kotlin and Java.
Kotlin:
fun optString(json: JSONObject, key: String, fallback: String?): String? {
var stringToReturn = fallback
if (!json.isNull(key)) {
stringToReturn = json.optString(key, null)
}
return stringToReturn
}
Java:
public static String optString(JSONObject json, String key, String fallback) {
String stringToReturn = fallback;
if (!json.isNull(key)) {
stringToReturn = json.optString(key, null);
}
return stringToReturn;
}
Simply pass in null for the fallback parameter if you don't need the fallback.

I ended up creating a utility class for this purpose:
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
final public class JsonUtil {
#Nullable
public static String optString(
#NonNull JSONObject object,
#NonNull String key
) throws JSONException {
if (object.has(key) && !object.isNull(key)) {
return object.getString(key);
}
return null;
}
}

I do like this...
String value;
if(jsonObject.get("name").toString().equals("null")) {
value = "";
}else {
value = jsonObject.getString("name");
}

if (json != null && json.getString(KEY_SUCCESS) != null){
// PARSE RESULT
}else{
// SHOW NOTIFICIATION: URL/SERVER NOT REACHABLE
}
that is for checking json null with there key word.
JSONObject json = new JSONObject("{\"hello\":null}");
json.getString("hello");
this you get is String "null" not null.
your shoud use
if(json.isNull("hello")) {
helloStr = null;
} else {
helloStr = json.getString("hello");
}
first check with isNull()....if cant work then try belows
and also you have JSONObject.NULL to check null value...
if ((resultObject.has("username")
&& null != resultObject.getString("username")
&& resultObject.getString("username").trim().length() != 0)
{
//not null
}
and in your case also check
resultObject.getString("username").trim().eqauls("null")
If you must parse json first and handle object later, let try this
Parser
Object data = json.get("username");
Handler
if (data instanceof Integer || data instanceof Double || data instanceof Long) {
// handle number ;
} else if (data instanceof String) {
// hanle string;
} else if (data == JSONObject.NULL) {
// hanle null;
}

My Josn parser was long and had to create a new class to fix that,
then just had to add 1 extra line in each method and rename current JSONObject property name, so all other calls were referencing to my new class instead to JSONObject.
public static ArrayList<PieceOfNews> readNews(String json) {
if (json != null) {
ArrayList<PieceOfNews> res = new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
//before JSONObject jo = jsonArray.getJSONObject(i);
JSONObject joClassic = jsonArray.getJSONObject(i);
//facade
FixJsonObject jo = new FixJsonObject(joClassic);
PieceOfNews pn = new PieceOfNews();
pn.setId(jo.getInt("id"));
pn.setImageUrl(jo.getString("imageURL"));
pn.setText(jo.getString("text"));
pn.setTitle(jo.getString("title"));
pn.setDate(jo.getLong("mills"));
res.add(pn);
}
return res;
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
Here is my class with the methods I needed, you can add more
public class FixJsonObject {
private JSONObject jsonObject;
public FixJsonObject(JSONObject jsonObject) {
this.jsonObject = jsonObject;
}
public String optString(String key, String defaultValue) {
if (jsonObject.isNull(key)) {
return null;
} else {
return jsonObject.optString(key, defaultValue);
}
}
public String optString(String key) {
return optString(key, null);
}
public int optInt(String key) {
if (jsonObject.isNull(key)) {
return 0;
} else {
return jsonObject.optInt(key, 0);
}
}
public double optDouble(String key) {
return optDouble(key, 0);
}
public double optDouble(String key, double defaultValue) {
if (jsonObject.isNull(key)) {
return 0;
} else {
return jsonObject.optDouble(key, defaultValue);
}
}
public boolean optBoolean(String key, boolean defaultValue) {
if (jsonObject.isNull(key)) {
return false;
} else {
return jsonObject.optBoolean(key, defaultValue);
}
}
public long optLong(String key) {
if (jsonObject.isNull(key)) {
return 0;
} else {
return jsonObject.optLong(key, 0);
}
}
public long getLong(String key) {
return optLong(key);
}
public String getString(String key) {
return optString(key);
}
public int getInt(String key) {
return optInt(key);
}
public double getDouble(String key) {
return optDouble(key);
}
public JSONArray getJSONArray(String key) {
if (jsonObject.isNull(key)) {
return null;
} else {
return jsonObject.optJSONArray(key);
}
}
}

If values for key is null like below
{
"status": 200,
"message": "",
"data": {
"totalFare": null,
},
}
check with "isNull" , for Eg:
String strTotalFare;
if (objResponse.isNull("totalFare"))
{
strTotalFare = "0";
} else {
strTotalFare = objResponse.getString("totalFare");
}
if value is "null" for key "totalFare", above function will enter in if and assign value zero else it will get actual value from key.

Related

How to build test data builder for json model

I have a microservice/application that accepts a JSON and convert to java POJO that is processed further in that application. Say the structure is:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "a"
}
// some other properties
}
public class Hazmat {
private String hazmatName;
}
public class POJO {
private Header header;
private Hazmat hazmet;
}
Here the "hazmat" could be present or absent. For all test data, the value of header and msgTs doesn't matter. So we can hard code the value;
Now to test it I would like to create a test data builder. The builder will be like this:
public class PojoBulider {
private String hazmatName;
public PojoBuilder withHamatName(String hazmatName) { this.hazmatname = hazmatName; return this; }
public String build() {
// generate test data from the captured inputs eg "hazmatName".
}
}
for generating the test data the user input / feature file column value will work with a few selected properties (eg hazmatName). The rest can be hard coded.
Now the problem is how can we hard code the fixed value such as msgTs? I can have a template json:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
Then have:
public void build() {
String templateJson; // load from file;
templateJson = templateJson.replaceAll("%%hazmatName%%", hazmatName);
return templateJson;
}
The thing is that the JSON can have properties that are present and absent. So I cannot have multiple templateJson with different possible value ie one templateJson:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
another template json:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"toy": {
"name": "%%toyName%%"
}
}
I can't have one template json as:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"toy": {
"name": "%%toyName%%"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
Because not test data will have both "toy" and "hazmat" section.
So I am stuck. I can probably have multiple template json like one for hazmat, hazmat.json:
"hazmat": {
"name": "%%hazmatName%%"
}
and another for toy:
"toy": {
"name": "%%toyName%%"
}
and combine them like:
public String build() {
if (hazmatName != null) {
// load hazmatJson
// append to templateJson
}
if (toyName != null) {
// load toyJson
// append to templateJson
}
return templateJson;
}
I would like to use the POJO instead:
public String build() [
Pojo pojo = new Pojo();
Hazmat hazmat = new Hazmat();
hazmat.setHazmatName(this.hazmatName);
pojo.setHazmat(hazmat);
return new ObjectMapper().writeValueAsString(pojo);
}
but the problem is how can I populate the header, etc value that don't change for all json. I can have another json:
{
"header": { "msgTs": "..." } }
and then load it using ObjectMapper load:
public String build() {
Header header = new ObjectMapper().load("header.json");
pojo.setHeader(header);
}
Is there a pure java based approach without using any json file altogether (ie header.json, toy.json, hazmat.json)? how do normally people generate test data in this case?
As you commented that you prefer to modify fields over Key-based mappings, I write this answer explaining what I would do under that constraint (not saying that this is the best solution, as I would use constant keys with maps).
Still assuming, that you ultimately want to generate a json-like String as input for your test candidate, I would create a class that prints itself to json format. Be aware, that I only tested for Object-arrays, not primitive arrays! List, Map and Set types are also not included, but you can add them yourself, if you like.
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public abstract class JSON {
public static final Object UNDEFINED = new Object();
public String toJsonThrowRTE() {
try {
return toJsonString();
} catch (Throwable t) {
throw new RuntimeException("I found thiz. May I keep it? :)", t);
}
}
public String toJsonString() throws NoSuchMethodException, SecurityException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Field field : getAllDeclaredFields()) {
String name = field.getName();
// This prevents endless recursion.
if (name.startsWith("this")) {
continue;
}
Class<?> fieldType = field.getType();
if (fieldType.isPrimitive()) {
// No need for the first field to have a ',' before it.
if (first) {
first = false;
} else {
sb.append(",\n");
}
// This is cumbersome, but I have no cleaner solution.
sb.append(name).append(": ");
switch (fieldType.getTypeName()) {
case "int":
sb.append(field.getInt(this));
break;
case "long":
sb.append(field.getLong(this));
break;
case "boolean":
sb.append(field.getBoolean(this));
break;
case "char":
sb.append("'" + field.getChar(this) + "'");
break;
case "double":
sb.append(field.getDouble(this));
break;
case "float":
sb.append(field.getFloat(this));
break;
case "byte":
sb.append(field.getByte(this));
break;
case "short":
sb.append(field.getShort(this));
break;
}
} else {
String value = valueToString(field.get(this));
if (value != null) {
// No need for the first field to have a ',' before it.
if (first) {
first = false;
} else {
sb.append(",\n");
}
sb.append(name).append(": ").append(value);
}
}
}
return "{\n" + indent(sb.toString()) + "\n}";
}
public String valueToString(Object value) throws NoSuchMethodException, SecurityException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
if (value == null) {
return "null";
} else if (value == UNDEFINED) {
return null;
} else if (value instanceof JSON) {
JSON childJson = (JSON) value;
return childJson.toJsonString();
} else if (value instanceof String) {
return "\"" + value + "\"";
} else if (value instanceof Character) {
return "'" + value + "'";
} else if (value.getClass().isArray()) {
Object[] array = (Object[]) value;
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Object o : array) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(valueToString(o));
}
return "[ " + sb.toString() + " ]";
}
// Everything else is just toString.
return value.toString();
}
public List<Field> getAllDeclaredFields() {
List<Field> allFields = new ArrayList<>();
// We start with the current class, and stop at JsonStringBuilder.
// After that, the fields are Object fields, and we don't want those.
Class<?> currentClass = getClass();
while (JSON.class.isAssignableFrom(currentClass)) {
// We want to order the fields from the most general to the most specific,
// so we must add the new fields at the start.
List<Field> declaredFields = Arrays.asList(currentClass.getDeclaredFields());
List<Field> childFields = allFields;
allFields = new ArrayList<>(childFields.size() + declaredFields.size());
allFields.addAll(declaredFields);
allFields.addAll(childFields);
currentClass = currentClass.getSuperclass();
}
return allFields;
}
public String indent(String toIndent) {
return toIndent.replaceAll("(?:^|(\\n))", "$1\t");
}
}
All objects you derive from this class will print themselves to json on command. This is the most powerful I can come up with on a short notice, but I think it should do.
You can now create any POJO with constructor and such, so you can set up your test, by creating you default object and then adding the required test values on demand. Objects that are JSON.UNDEFINED are not printed.
Here is an example on how to use it:
#Test
public void test() {
JSON topLevel = new JSON() {
Object msgTs = "2020-02-20T11:00:00";
Object name = "a";
Object[] someArray = { 7, "String intermix", 'k', 5d };
Object iAmNull = null;
Object undefined = JSON.UNDEFINED;
Object someChild = new JSON() {
int someInt = 42;
char myChar = 'j';
};
};
System.out.println(topLevel.toJsonThrowRTE());
}
The above "test" will print this String to console:
{
msgTs: "2020-02-20T11:00:00",
name: "a",
someArray: [ 7, "String intermix", 'k', 5.0 ],
iAmNull: null,
someChild: {
someInt: 42,
myChar: 'j'
}
}
Now you just have to insert this string into your Json parser or whatever you want to test. This would be your base object, which you create the same way with the #Before or #BeforeAll, depending on your junit version. And from there you can modify the object per test. Remember to declare fields that may or may not be used as JSON.UNDEFINED, so that you can assign a useful value, but they are not printed, unless you set them!
JSON message = new JSON() {
Object header = new JSON() {
String msgTs = "2020-02-20T11:00:00";
};
Object hazmet = JSON.UNDEFINED;
Object toy = JSON.UNDEFINED;
// ...
};

Getting error when trying to extract value for a specific key from different node levels

I am trying to extra value for avatar from all different node. My json looks like this
{
"page":1,
"per_page":3,
"total":12,
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg",
"total_pages":4,
"data":[
{
"id":1,
"first_name":"George",
"last_name":"Bluth",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
},
{
"id":2,
"first_name":"Janet",
"last_name":"Weaver",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
},
{
"id":3,
"first_name":"Emma",
"last_name":"Wong",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
}
],
"user":{
"id":3,
"first_name":"Emma",
"last_name":"Wong",
"avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
}
}
I have tried following solution
public void getAllParentChildNodeAsMap(JSONObject jObject, Map<String, Object> result) throws JSONException {
Iterator<String> iterator = jObject.keys();
while (iterator.hasNext()) {
String key = (String) iterator.next();
Object value = null;
if (jObject.getJSONObject(key) instanceof JSONObject) {
JSONObject jsonValue = jObject.getJSONObject(key);
getAllParentChildNodeAsMap(jsonValue, result);
} else {
value = jObject.get(key);
}
if(key.equals("avatar")) {
result.put(key, value);
}
}
log.info(result.values().toString());
}
And it keeping giving me following error
org.json.JSONException: JSONObject["per_page"] is not a JSONObject.
at org.json.JSONObject.getJSONObject(JSONObject.java:782)
at com.rnd.restapi.serenity.steps.CommonFacilities.getAllParentChildNodeAsMap(CommonFacilities.java:72)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f.CGLIB$getAllParentChildNodeAsMap$5(<generated>)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f$$FastClassByCGLIB$$bb25cc09.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at net.thucydides.core.steps.BaseMethodRunner.invokeMethod(BaseMethodRunner.java:10)
at net.thucydides.core.steps.NormalMethodRunner.invokeMethodAndNotifyFailures(NormalMethodRunner.java:20)
at net.thucydides.core.steps.StepInterceptor.runNormalMethod(StepInterceptor.java:390)
at net.thucydides.core.steps.StepInterceptor.testStepResult(StepInterceptor.java:161)
at net.thucydides.core.steps.StepInterceptor.intercept(StepInterceptor.java:72)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f.getAllParentChildNodeAsMap(<generated>)
at com.rnd.restapi.serenity.steps.CommonFacilities.getAllParentChildNode(CommonFacilities.java:64)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f.CGLIB$getAllParentChildNode$4(<generated>)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f$$FastClassByCGLIB$$bb25cc09.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at net.thucydides.core.steps.StepInterceptor.invokeMethod(StepInterceptor.java:478)
at net.thucydides.core.steps.StepInterceptor.executeTestStepMethod(StepInterceptor.java:463)
at net.thucydides.core.steps.StepInterceptor.runTestStep(StepInterceptor.java:438)
at net.thucydides.core.steps.StepInterceptor.runOrSkipMethod(StepInterceptor.java:179)
at net.thucydides.core.steps.StepInterceptor.testStepResult(StepInterceptor.java:166)
at net.thucydides.core.steps.StepInterceptor.intercept(StepInterceptor.java:72)
at com.rnd.restapi.serenity.steps.CommonFacilities$$EnhancerByCGLIB$$d9a1a28f.getAllParentChildNode(<generated>)
at com.rnd.restapi.tests.CountriesSearchTests.get_service_is_successful_and_status_code(CountriesSearchTests.java:32)
at ✽.Get service is successful and status code 200(src/test/resource/feature/get.feature:7)
You should use optJSONObject method if you are not sure what kind of JSON node it is behind given key. getJSONObject method throws org.json.JSONException exception when given value is not JSONObject. Below you can find fixed method implementation:
void getAllParentChildNodeAsMap(JSONObject jObject, List<String> result) {
for (String key : jObject.keySet()) {
if (key.equals("avatar")) {
result.add(jObject.getString(key));
continue;
}
JSONObject value = jObject.optJSONObject(key);
if (value != null) {
getAllParentChildNodeAsMap(value, result);
continue;
}
JSONArray array = jObject.optJSONArray(key);
if (array != null) {
for (int i = 0; i < array.length(); i++) {
JSONObject item = array.optJSONObject(i);
if (item != null) {
getAllParentChildNodeAsMap(item, result);
}
}
}
}
}
It is much useful to return List with avatar URL-es because for each URL avatar is a key.

Response from Retrofit can't get object value

{ "StatusCode": 200, "StatusDescription": "OK", "ErrorMessage":
"", "ErrorDetail": "", "Results": [
{
"Key": "AccessTokens",
"Value": "[{\"Key\":\"XXXXX",
\"Value\":\"BABABA\"},{\"Key\":\"DIDADIDA\",\"Value\":\"YYYYY"
} ]"}]}
This is the response i will get when i success call the API. The datatype of "Results" is List. Can anyone explain for me how to get the "Key" and the "Value".
My Object Classes
public class KeyValueItem {
private String Key;
private String Value;
public String getKey() {
return Key;
}
public void setKey(String key) {
Key = key;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
}
Response Class
public class RestServiceResponse {
#SerializedName("StatusCode")
#Expose
public int StatusCode;
public int getStatusCode() {
return StatusCode;
}
#SerializedName("StatusDescription")
#Expose
public String StatusDescription;
public String getStatusDescription() {
return StatusDescription;
}
#SerializedName("ErrorMessage")
#Expose
public String ErrorMessage;
public String getErrorMessage() {
return ErrorMessage;
}
#SerializedName("ErrorDetail")
#Expose
public String ErrorDetail;
public String getErrorDetail() {
return ErrorDetail;
}
#SerializedName("Results")
#Expose
public List<KeyValueItem> Results;
public List<KeyValueItem> getResults() {
return Results;
}
}
Anyone help please =(
Some of my code:
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
JSONArray jsonArray = new JSONArray(list);
try {
JSONObject job = jsonArray.getJSONObject(1);
String testttt = job.getString("Key");
Log.i("dsadsadsadas", testttt);
} catch (JSONException e) {
e.printStackTrace();
}
}
2 things you have to understand first.
Your JSON data is not in valid format. It contains \ (slashes) to escape double quotes in key-value pair. To confirm whether the returned JSON data is valid or not please copy & paste your JSON response into JSON validator and Formatter. Maybe problem in server script.
If you're using GsonConvertorFactory with Retrofit, Retrofit will automatically converts JSON response data to POJO internally. So, you don't need parse it again inside onResponse() method. If you get proper JSON response from server side then use it like below.
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
// code....
RestServiceResponse restServiceResponse = response.body();
if (restServiceResponse.getStatusCode() == 200) {
List<KeyValueItem> list = response.body().getResults();
for(int i = 0; i < list.size(); i++) {
KeyValueItem kvi = list.get(i);
// do whatever you want with kvi object
}
}
}
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
for(KeyValueItem keyValueItem : list) {
String key = keyValueItem.getKey();
String value = keyValueItem.getValue();
Log.i("Keykeykey", key);
}
try {
JSONArray jsonArray = new JSONArray(value);
for(int i = 0; i < jsonArray.length();i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String keykey = obj.getString("Key");
String VAlll = obj.getString("Value");
Log.i("c1111",keykey);
Log.i("c222222", VAlll);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}else if(restServiceResponse.getErrorMessage() != null){
builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle("Error");
builder.setMessage(restServiceResponse.getErrorMessage());
builder.setPositiveButton("Ok",null);
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
OK. Btw. i have try this to get my result. and it works!
To answer those about a invalid JSON format maybe because i have changed the value of the JSON so may have some mistake on it.
Below is the final log i get:
74/com.appandus.user.konnect I/Keykeykey: AccessTokens 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: XXXXX 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c222222: BABABA
07-12 17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: NS/NH
: DIDAIDA 07-12 17:14:38.177 6274-6274/com.appandus.user.konnect
I/c222222: YYYYYY

validate a JSON object using jax-rs

I've a requirement. lets say I have a JSON file as shown below.
{
"orgId": 27,
"orgType":"MotorBikes",
"orgName":"ROYAL Enfield",
"orgAddress":"Express Estate",
"orgCity":"Chennai",
"orgState":"TamilNadu"
}
So I need to do two validations. one is checking all the json fields and return true or false and second one should have methods to validate partial response like for example: isExists(jsonObject, "orgType":"MotorBikes") should return true. This comparison should be done using jax-rs libraries. So if anybody who is familiar with this please tell me. This would help me a lot.
Package javax.json should be enough.
import javax.json.JsonObject;
public static void main(String[] args){
JsonObject jsonObj = /* your json */;
boolean all = checkAll(jsonObj,new String[]{"orgId","orgType","orgName","orgAddress","orgCity","orgState"});
boolean one = isExists(jsonObj,"orgType","MotorBikes");
}
private boolean checkAll(JsonObject jsonObj, String[] keys) {
for(String key: keys) {
if(jsonObj.get(key)==null) return false;
}
return true;
}
private boolean isExists(JsonObject jsonObj, String key, String value) {
return (jsonObj.get(key)!=null && jsonObj.get(key).equals(value));
}
UPDATE:
A more focused answer using org.json library which is in your dependency and is a JSON library, not JAX-RS.
#Test
public void test() throws FileNotFoundException{
String jsonAsString = when().get("/your.get").then().contentType(ContentType.JSON).extract().response().asString();
JSONObject jsonFromResponse = new JSONObject(jsonAsString);
File file = /** Load your file ***/
FileInputStream is = new FileInputStream(file);
JSONTokener tokener = new JSONTokener(is);
while(tokener.more()) { // Iterate through Json file
JSONObject obj = (JSONObject) tokener.nextValue();
for(String key: obj.keySet()) {
boolean valid = validateField(key, jsonFromResponse);
System.out.println("'"+key+"' field "+(valid?"not ":"")+"present");
}
}
boolean v = validateValue(jsonFromResponse, "orgName", "ROYAL Enfield");
System.out.println("Validation: "+v);
}
private boolean validateValue(JSONObject json, String key, String value) {
if(validateField(key,json))
return value.equals(json.getString(key));
return false;
}
private boolean validateField(String key, JSONObject jsonFromResponse) {
Object valueFromResponse = null;
try {
valueFromResponse = jsonFromResponse.get(key);
}
catch(JSONException e){
valueFromResponse = null;
}
return valueFromResponse!=null;
}

Recursive function not working for to get innermost exception message

I have written this method
private string FindInnerExceptionMessage(Exception ex)
{
string exceptionMsg = string.Empty;
if (ex.InnerException == null)
{
exceptionMsg = ex.Message;
}
else
{
ex = ex.InnerException;
FindInnerExceptionMessage(ex);
}
return exceptionMsg;
}
However, after that FindInnerExceptionMessage it is stepping to return exceptionMsg and not logging the exact exception message
You don't actually assign the return value of your recursive call to anything. As a result, your first call will return String.Empty because the value of FindInnerExceptionMessage(ex.InnerException) is never assigned as the return value (unless the exception passed to the first call has no inner exception, in which case it will work). Try something like this:
private string FindInnerExceptionMessage(Exception ex)
{
string exceptionMsg = string.Empty;
if (ex.InnerException == null)
{
exceptionMsg = ex.Message;
}
else
{
exceptionMsg = FindInnerExceptionMessage(ex.InnerException);
}
return exceptionMsg;
}

Categories

Resources