My API response contains a blank array: []
how to validate?
For positive scenarios i have jsonarray and jsonobject . here am not sure how to validate the empty array.
public void ValidateEmptyArray() throws JSONException {
try {
if(responseJObject.isEmpty()) {
report.reportPassEvent("Validate cause attribute", "cause value is -"+ responseJObject.getString("cause"));
} else {
report.assertFailEvent("Validate cause attribute", "cause value is -"+ responseJObject.getString("cause")+
" And expected value is - "+cause);
}
} catch(Exception e) {
report.assertFailEvent("Validate cause attribute", "cause attribute is not present in the response");
}
}
Related
I have a stream like this,
List<String> test = Arrays.asList("1", "2,", "3");
test.stream().map(t -> {
try {
validate(t);
} catch (Exception e) {
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e);
}
return true;
})
In case of an exception, I would like to store it somewhere, process the next element and then show all exceptions at once. Is this possible?
Well, don't rethrow the exception:
var exceptions = test.stream().map(t -> {
try {
validate(t);
} catch (Exception e) {
return e;
}
return null;
})
.filter(Objects::nonNull) // if you don't need to preserve the index
.toList();
I modified your code slightly. Your main issue is that you're re-throwing that exception when you catch it -- that will stop processing at the first exception. Then you need some way to store the inputs that cause an error (that's what invalidInputs is for. I'm assuming that your next step is to actually use the results of that input to convert, otherwise you don't need to use map(), so my "validate" method also just does the conversion too. I use a JUnit test harness for stuff like this, and I left in the assert()s; you should take them (and the #Test annotation) out for your code.
//throws NumberFormatException if input doesn't parse into an integer
public static Integer validate(String input) throws Exception{
return Integer.parseInt(input);
}
#Test
public void testStreamMap() {
List<String> test = Arrays.asList("1", "2,", "3");
List<String> invalidInputs = new ArrayList<>();
List<Integer> result= test.stream().map(t -> {
Integer localResult;
try {
localResult=validate(t);
} catch (Exception e) {
invalidInputs.add(t);
localResult=null;
}
return localResult;
}).collect(Collectors.toList());
assertTrue(invalidInputs.contains("2,"));
assertFalse(result.contains(2));
}
You can try this approach to collect all the exceptions in a list as follows:
Here,
I have iterated over the list using forEach and in case of catch , added the exception e in the listOfExceptions list.
As I have entered three invalid inputs in the list , it is giving three exceptions in the list at the end corresponding to each element which is giving exception.
For the demo purpose, I have created one more list listOfElementsWithoutExceptions showing the elements which are processed without any exceptions.
Note: You can have your own custom exception list in place of List<Exception>.
public class Test2 {
public static void main(String[] args) {
List<String> test = Arrays.asList("test1", "test2", "3","4","test5","6");
List<Exception> listOfExceptions = new ArrayList<>();
List<String> listOfElementsWithoutExceptions = new ArrayList<>();
test.forEach(t -> {
try {
validate(t);
listOfElementsWithoutExceptions.add(t);
} catch (Exception e) {
listOfExceptions.add(e);
}
});
System.out.println("list of exceptions:: " + listOfExceptions);
System.out.println("list of elements without exceptions:: "+ listOfElementsWithoutExceptions);
}
private static void validate(String t) {
Integer.parseInt(t);
}
}
Output:
list of exceptions::
[java.lang.NumberFormatException: For input string: "test1",
java.lang.NumberFormatException: For input string: "test2",
java.lang.NumberFormatException: For input string: "test5"]
list of elements without exceptions:: [3, 4, 6]
public String deleteCounterParty(List<CounterParty>counterParties)
{
String message = "";
for(CounterParty counterParty:counterParties) {
if (counterParty.getId() != null && counterPartyRepository.getById(counterParty.getId()) != null) {
counterPartyRepository.deleteById(counterParty.getId());
message="deleted successfully";
}
else {
message="id not found";
}
}
return message;
}
I'm using this method to delete rows by giving list of ids if the given id is found it is deleted,if not it throws this EmptyResultDataAccessException help me fix this
Data access exception thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned.
Use a try-catch block to catch the exception if thrown and alter your logic accordingly so that when the code follows a happy path, at least one row is returned.
try { //code to delete rows } catch(final
EmptyResultDataAccessException e) { //exception message }
I need to write a code which would convert JSON file to CSV. The problem is in a format that the CSV file should look like.
Input json:
{
"strings":{
"1level1":{
"1level2":{
"1label1":"1value1",
"1label2":"1value2"
}
},
"2level1":{
"2level2":{
"2level3":{
"2label1":"2value1"
},
"2label2":"2value2"
}
}
}
}
And this is expected csv file for this json:
Keys,Default
1level1.1level2.1label1,1value1
1level1.1level2.1label2,1value2
2level1.2level2.2level3.2label1,2value1
2level1.2level2.2label2,2value2
I was trying to go through JSON file using recursion but this didn't work for me because of rewriting JSON object on each iteration and code was working only till the first value. Are there any suggestions about how can it be done?
Note: have tried to use different JSON libraries, so for now can be used any of them
UPDATE #1:
Non-working code example I was trying to use to go through JSON tree:
public static void jsonToCsv() throws JSONException {
InputStream is = MainClass.class.getResourceAsStream("/fromJson.json");
JSONTokener jsonTokener = new JSONTokener(is);
JSONObject jsonObject = new JSONObject(jsonTokener);
stepInto(jsonObject);
}
private static void stepInto(JSONObject jsonObject) {
JSONObject object = jsonObject;
try {
Set < String > keySet = object.keySet();
for (String key: keySet) {
object = object.getJSONObject(key);
stepInto(object);
}
} catch (JSONException e) {
Set < String > keySet = object.keySet();
for (String key: keySet) {
System.out.println(object.get(key));
}
e.printStackTrace();
}
}
UPDATE #2:
Another issue is that I will never know the names of the JSON object and count of child objects (update JSON and CSV examples as well to make the image more clear). All that is known, that it will always start with strings object.
Library used:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
So found a solution by myself:
public static void jsonToCsv() throws JSONException, IOException {
InputStream is = MainClass.class.getResourceAsStream("/fromJson.json");
JSONTokener jsonTokener = new JSONTokener(is);
JSONObject jsonObject = new JSONObject(jsonTokener).getJSONObject("strings");
builder = new StringBuilder();
while (!jsonObject.isEmpty()) {
stepInto(jsonObject);
}
String[] lines = builder.toString().split("\n"); // builder lines are in reverse order from expected so this array is used to reverse them
FileWriter csvWriter = new FileWriter("src/main/resources/toCsv.csv");
csvWriter.append("Keys,Default (en_US)\n");
for (int i = lines.length - 1; i >= 0; i--) {
csvWriter.append(lines[i]).append("\n");
}
csvWriter.flush();
csvWriter.close();
}
private static void stepInto(JSONObject jsonObject) {
for (String key: jsonObject.keySet()) {
Object object = jsonObject.get(key);
if (object instanceof JSONObject) {
builder.append(key).append(".");
stepInto(jsonObject.getJSONObject(key));
} else {
builder.append(key).append(",").append(object).append("\n");
jsonObject.remove(key);
break;
}
if (jsonObject.getJSONObject(key).isEmpty()) {
jsonObject.remove(key);
}
break;
}
}
I think you just missed keeping track of your result, otherwise it looks good.
Let's say your result is a simple string. Then you have to concatenate all keys while traversing the json object until you reach a primitive value (like a number or a string).
(I am writing this out of my head, so please forgive me for incorrect syntax)
private static String stepInto(JSONObject jsonObject) { // we change "void" to "String" so we can record the results of each recursive "stepInto" call
//JSONObject object = jsonObject; // we don't need that. Both variables are the same object
String result ="";
try {
for (String key: jsonObject.keySet()) { // shorter version
Object object = jsonObject.get(key); // Attention! we get a simple Java Object
if(object instanceof JSONObject){
result+= key+"."+stepInto(jsonObject.getJSONObject(key)); // the recursive call, returning all keys concatenated to "level1.level2.level3" until we reach a primitive value
}
if(object instanceof JSONArray){
result+= key+", "+ ... // notice how we use the csv separator (comma) here, because we reached a value. For you to decide how you want to represent arrays
}
result+= key +", "+ object +"\n"; // here I am not sure. It may well be that you need to check if object is a String an Integer, Float or anything.
}
} catch (JSONException e) {
for (String key: jsonObject.keySet()) {
System.out.println(object.get(key));
}
e.printStackTrace();
result+= "\n"; // I added this fallback so your program can terminate even when an error occurs.
}
return result; // sorry, I forgot to accumulate all results and return them. So now we have only one actual "return" statement that will terminate the call and return all results.
}
As you can see, I didn't change much of your original method. The only difference is that now we keep track of the keys ("level1.level2...") for each recursive call.
EDIT
I added a +"\n"; so everytime we reach a value so we can terminate that "line".
AND more importantly, instead of returning everytime, I add the result of each call to a string, so we continue looping over the keys and concatenate all results. Each call of the method will return only once all keys are looped over. (sorry that missed that)
In your calling method you could print out the result, something like that:
JSONObject jsonObject = new JSONObject(jsonTokener);
String result = stepInto(jsonObject);
System.out.println(result);
Below code...
#GetMapping("/brian/{number}")
public String getBrianMessage(#PathVariable int number) throws NumberFormatException {
try {
logList.add(number);
String stringList = logList.toString();
return "List is " + stringList;
} catch (NumberFormatException e){
int newCount= 999;
logList.add(newCount);
String stringList = logList.toString();
return "List is " + stringList;
}
}
When going to the url i would like the integer stored in a list. This works fine when you use a valid integer value. I want the ability to default the value to 999 when a string is supplied. So, if i go to /brian/string it should add 999 to the list and return it. This is not working and I'm getting the same error as before I added the exception handling
I try to get patient information, by sending an ID to the server. I expect the result to be a JSONObject, as only one patient corresponds with the ID. However, what i get is a JSONArray. I have tried to do getJSONObject(0), but it gives this error:
Index 0 out of range [0..0)
Why i is an Array and not an Object, and how do i deal with it?
This is my java code in the activity:
new HttpRequestTask(
"getPatientFull",
new String[]{"ID"},
new String[]{PatientID}, new HttpRequestTask.ResultReceiver() {
#Override
public void processResult(String apiFunctionName, JSONObject result) {
if (result != null) {
try {
if (result.has("error")) {
shorttoast("ERROR: " + result.getString("error") + "saving patient file");
} else {
if (result.has("patient_details")) {
patientName = result.getJSONArray("patient_details").getJSONObject(0).getString("NAME");
shorttoast(patientName);
}
}
} catch (JSONException ex) {
shorttoast("ERROR" + ex.getLocalizedMessage());
}
} else
shorttoast("Retreiving failed");
}
}).execute();
The PatientID is defined earlier in the code (it's an existing patient id).
and this is the php API function that was defined by my teacher:
app.post("/getPatientFull", function (req, res) {
pool.getConnection(function (err, connection) {
connection.query('SELECT * FROM PatientDossier WHERE PATIENT_ID=?',
[req.query.ID],
function (error, results, fields) {
if (error) {
res.status(403).json({"error": error.code});
} else {
res.status(200).json({patient_details:results});
}
});
connection.release();
});
});
The PHP function does not return a single object, it returns an array.
So, you should expect a JSONArray on the Android side.
As to why getJSONObject(0) is giving you an out-of-bounds error, I'm not sure.
Try using the debugger to look at the JSONArray, and see what's in it. It's possible that you searched for a patient id that's not in the database, and the PHP code returned an empty array. Your code should be checking that anyway.
It also looks like maybe "result" is a JSONObject containing the array, under the key "patient_details", in which case, you need to get the value of "patient_details" and index into that array. If you show us the JSON response, it would be easier to tell.