My API is returning me this:
[
{
"id": 1,
"uuid": "#B7304",
"username": "blabla",
"hearthBeat": 30,
"status": "well",
"date": "13/05/1333",
"latitute": 30,
"longitude": 40,
"cardiacSteps": 50
},
{
"id": 2,
"uuid": "#B7304",
"username": "blabla",
"hearthBeat": null,
"status": null,
"date": null,
"latitute": null,
"longitude": null,
"cardiacSteps": null
}
]
The problem is, I would like to, on the array that is represented by the second ID, return a error message, as there is no data in it. Something like this:
[
{
"id": 1,
"uuid": "#B7304",
"username": "blabla",
"hearthBeat": 30,
"status": "well",
"date": "13/05/1333",
"latitute": 30,
"longitude": 40,
"cardiacSteps": 50
},
{
"uuid": #B7304,
"message": "This user has no data"
}
]
My code is as follows:
#GetMapping("/monitored")
#PreAuthorize("hasRole('USER') and hasRole('RESPONSIBLE')")
public Object returnMonitored() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Optional<User> username = userRepository.findByUsername(auth.getName());
List<Dependency> uuids = dependencyRepository.returnAllUserUuid(Objects.requireNonNull(username.orElse(null)).getUuid());
List<Health> health = new ArrayList<>();
uuids.forEach(uuid -> {
if (userRepository.existsByUuid(uuid.getUserUuid()) && healthRepository.existsByUuid(uuid.getUserUuid())) {
if(healthRepository.existsByUuid(uuid.getUserUuid()) && healthRepository.isRegistered(uuid.getUserUuid())) {
List<Health> healthList = healthRepository.returnAllUserUuid(uuid.getUserUuid());
health.addAll(healthList);
}
}
}
);
if(health == null || health.isEmpty()) {
return ResponseEntity.ok().body(new MessageVo("You're not responsible for any user ;) "));
}
return health;
}
With this, I can't seem to override the specific response, as it is an List of the Entity(Health).
Thanks for your help!
What you want to do is a really bad idea since one would expect all elements in a JSON array to have the same attributes.
You should return what you are returning now with all the nulls and return your "message" in status.
[
{
"id": 1,
"uuid": "#B7304",
"username": "blabla",
"hearthBeat": 30,
"status": "well",
"date": "13/05/1333",
"latitute": 30,
"longitude": 40,
"cardiacSteps": 50
},
{
"id": 2,
"uuid": "#B7304",
"username": "blabla",
"hearthBeat": null,
"status": "This user has no data",
"date": null,
"latitute": null,
"longitude": null,
"cardiacSteps": null
}
]
I would also recommend adding a "statusCode" attribute where you can return a numerical code and have "status" represent the statusCode description since doing string compares on status isn't a good idea either.
In your health class, add the #JsonInclude(Include.NON_NULL), values that are null will not be shown on your response. Take note to use the boxed type and not the primitive type.
#JsonInclude(Include.NON_NULL)
public class Health {
Integer id;
String uuid;
...
String message;
}
I have a DataResponseDto.json
{
"data": [
{
"customRule": {
"code": null,
"executionType": "ON_SUCCESS",
"description": "Description",
"owners": null,
"type": "TWO",
"enabled": true,
"objectType": "TEST",
"syncObjectKPIs": null,
"inactive": false,
"responsible": null,
"id": "0AB58A47D3A64B56A6B74DA0E66935DD",
"embedded": true,
"value": null,
"variables": [],
"kafkaEventName": null,
"lastChanged": 1530091858490,
"createPerson": null,
"externalId": null,
"groups": null,
"eventType": "UPDATE",
"branches": null,
"executionOrder": null,
"createDateTime": null,
"cronExpression": null,
"udfMetaGroups": null,
"name": "Sample1",
"location": null,
"permissionsType": "USER",
"udfValues": null,
"conditions": null,
"actions": [
{
"name": "ChecklistInstance",
"parameters": {
"templateName": "checklist"
}
}
],
"syncStatus": "IN_CLOUD",
"executionLog": []
},
"customRule": {
"code": null,
"executionType": "ON_SUCCESS",
"description": "Description",
"owners": null,
"type": "TWO",
"enabled": true,
"objectType": "TEST",
"syncObjectKPIs": null,
"inactive": false,
"responsible": null,
"id": "5033296D138C45C385AC141E1157B4FE",
"embedded": true,
"value": null,
"variables": [],
"kafkaEventName": null,
"lastChanged": 1530091858490,
"createPerson": null,
"externalId": null,
"groups": null,
"eventType": "UPDATE",
"branches": null,
"executionOrder": null,
"createDateTime": null,
"cronExpression": null,
"udfMetaGroups": null,
"name": "Sample2",
"location": null,
"permissionsType": "USER",
"udfValues": null,
"conditions": null,
"actions": [
{
"name": "ChecklistInstance",
"parameters": {
"templateName": "checklist"
}
}
],
"syncStatus": "IN_CLOUD",
"executionLog": []
}
}],
"pageSize": 1,
"currentPage": 0,
"lastPage": 0,
"totalObjectCount": 1,
"truncated": false
}
And I have a class to map this JSON file.
public class DataResponseDto {
private List<Map> data;
private Integer pageSize;
private Integer currentPage;
private Integer lastPage;
private Long totalObjectCount;
private Boolean truncated;
// getter setter
...
}
Now I am using ObjectMapper to parse this JSON into a java class. It retrieved DataResponseDto with only 1 map in data. It should be 2 maps in data.
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
File file = new File(classLoader.getResource("mock/DataResponseDto.json").getFile());
ObjectMapper mapper = new ObjectMapper();
DataResponseDto dataResponseDto = mapper.readValue(file, DataResponseDto.class);
List<RuleDto> rules = dataResponseDto.getData().stream().map(m -> mapper.convertValue(m.get("customRule"), RuleDto.class)).collect(Collectors.toList());
I am getting rules.size() = 1, it should be 2
Your problem is with the private List<Map> data;
Map cannot have duplicate keys, consider using something else such as MultiKeyMap from apache commons (org.apache.commons.collections.map.MultiKeyMap).
You have duplicate keys customRule. Try to make customRules an array with the rules and re-run the code.
I would like to merge all the below objects as a single object recursively. Every time I run the code for every iteration I receive a string object, I am storing them in a list. List looks like below:
bean [String1, String2, String3]. These three strings are to be merged as a single string object.
String1:
[code=100,
response=
{
"testObjects": [
{
"updated": [
{
"attributes": {},
"id": "123"
},
{
"attributes": {},
"id": "456"
}
],
"timeCheckQuery": null,
"query": null,
"message": null,
"error": null,
"deleted": null,
"agentId": null,
"added": null
}
],
"message": null,
"error": null
}
]
String2:
[code=100,
response=
{
"testObjects": [
{
"updated": [
{
"attributes": {},
"id": "789"
},
{
"attributes": {},
"id": "759"
}
],
"timeCheckQuery": null,
"query": null,
"message": null,
"error": null,
"deleted": null,
"agentId": null,
"added": null
}
],
"message": null,
"error": null
}
]
String3:
[code=100,
response=
{
"testObjects": [
{
"updated": [
{
"attributes": {},
"id": "242"
},
{
"attributes": {},
"id": "951"
}
],
"timeCheckQuery": null,
"query": null,
"message": null,
"error": null,
"deleted": null,
"agentId": null,
"added": null
}
],
"message": null,
"error": null
}
]
output:
[code=300,
response=
{
"testObjects": [
{
"updated": [
{
"attributes": {},
"id": "123"
},
{
"attributes": {},
"id": "456"
},
{
"attributes": {},
"id": "789"
},
{
"attributes": {},
"id": "759"
},
{
"attributes": {},
"id": "242"
},
{
"attributes": {},
"id": "951"
}
],
"timeCheckQuery": null,
"query": null,
"message": null,
"error": null,
"deleted": null,
"agentId": null,
"added": null
}
],
"message": null,
"error": null
}
]
You could serialize the first object as a json string, then append that string with next object serialized and so on.
The value of the 'updated' field seems to be a JsonArray Structure.
What you have to do is have a Global Array that adds the values(value of the 'updated' field) from all the responses into a single JsonArray.
Using Gson Library you can do it as follows
JsonArray jsonarray = new JsonArray();
jsonarray.addAll(jsonObject1.get("updated").getAsJsonArray());
jsonarray.addAll(jsonObject2.get("updated").getAsJsonArray());
jsonarray.addAll(jsonObject2.get("updated").getAsJsonArray());
Now you can use this JsonArray inside any object as you need as your requirement needs.
EDITED MY QUESTION:
I've been working on my first ever programming and Android project.
In the following code I receive a:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.gson.JsonElement.toString()' on a null object reference
for trying to call a method on my result JSONOBJECT which was retrieved using a networking library: https://github.com/koush/ion and is being parsed using google GSON library.
A toast string message and a log.v reveals that the JSON object is being successfully passed with all the necessary elements included.(Or maybe not passed completely? The Log.v cuts off after some point.)
My confusion lies in the ability to call the toString() GSON method on result which leads to a successful toast message, while attempting to call any other GSON method like result.get(images_count).toString leads to my error. I tried to use if(result.isJsonNull()) before executing my code to make sure that result was not null, but even if result.isJsonNull() returns false my method calls returns the error.
My 2 Part Question
What is causing my returned JsonObject result to successfully execute some GSON library methods sucessfully(like toString()), while returning a NullPointer Exception for others as when I atttempt to reach a json element member through .get(string member)?
In the future, how could I place/recognize checkpoints where an object might return a NullPointerException? So far I only use Logging or Toasts to display current object/variable values. THANKS ANSWERED BY BRONX. I have to use breakpoints.
Code that results in the NullPointer Exception: (I have replaced my CLient-ID with xxxxxxx in order to keep it a secret from the internet).
Future<JsonObject> loading;
private void load() {
// don't attempt to load more if a load is already in progress
if (loading != null && !loading.isDone() && !loading.isCancelled())
return;
// load the tweets from album : gQxwy https://api.imgur.com/3/album/{id}
//https://api.imgur.com/3/album/{id}/images
String url = "https://api.imgur.com/3/album/gQxwy.json";
// This request loads a URL as JsonObject and invokes
// a callback on completion.
loading = Ion.with(this)
.load(url)
.setHeader("Authorization", "Client-ID " + "xxxxxxxxxxxxxxx")
.setLogging("ION_VERBOSE_LOGGING", Log.VERBOSE)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
// this is called back onto the ui thread, no Activity.runOnUiThread or Handler.post necessary.
if (e != null) {
Toast.makeText(Imgur.this, "Error loading tweets", Toast.LENGTH_LONG).show();
return;
}
//Here i test if the object is Null.It goes directly to excute else, showing that the object is not Null.
if(result.isJsonNull()){
Toast.makeText(Imgur.this, result.toString(), Toast.LENGTH_LONG).show();
}else {
Log.v("JSONOBJECT_STRING", result.toString());
Toast.makeText(Imgur.this, result.get("images_count").toString(), Toast.LENGTH_LONG).show();
}
}
});
}
Here is the LogCat which includes the successfully retrieved JSON Object(We can see the JSON Object in the Log.) The Json object DOES contain the element images_count.
LogCat:
03-21 21:24:26.395 8035-8061/? D/ION_VERBOSE_LOGGING﹕ (353 ms) https://api.imgur.com/3/album/gQxwy.json: Connection successful
03-21 21:24:26.405 8035-8061/? D/ION_VERBOSE_LOGGING﹕ (363 ms) https://api.imgur.com/3/album/gQxwy.json: Recycling keep-alive socket
03-21 21:24:26.407 8035-8035/? V/JSONOBJECT_STRING﹕ {"data":{"id":"gQxwy","title":"playlist","description":null,"datetime":1425872636,"cover":"c7iJOmN","cover_width":160,"cover_height":120,"account_url":"JohnnyJem","account_id":18800283,"privacy":"public","layout":"blog","views":574,"link":"http://imgur.com/a/gQxwy","favorite":false,"nsfw":null,"section":null,"images_count":10,"images":[{"id":"c7iJOmN","title":"Title","description":"Description","datetime":1425872636,"type":"image/gif","animated":true,"width":160,"height":120,"size":65008,"views":1175,"bandwidth":76384400,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/c7iJOmN.gifv","webm":"http://i.imgur.com/c7iJOmN.webm","mp4":"http://i.imgur.com/c7iJOmN.mp4","link":"http://i.imgur.com/c7iJOmN.gif","looping":true},{"id":"SYRfZPy","title":"Title","description":"Description","datetime":1425872638,"type":"image/gif","animated":true,"width":160,"height":120,"size":139574,"views":1054,"bandwidth":147110996,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/SYRfZPy.gifv","webm":"http://i.imgur.com/SYRfZPy.webm","mp4":"http://i.imgur.com/SYRfZPy.mp4","link":"http://i.imgur.com/SYRfZPy.gif","looping":true},{"id":"1aD2tdR","title":"Title","description":"Description","datetime":1425872639,"type":"image/gif","animated":true,"width":160,"height":120,"size":117092,"views":882,"bandwidth":103275144,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/1aD2tdR.gifv","webm":"http://i.imgur.com/1aD2tdR.webm","mp4":"http://i.imgur.com/1aD2tdR.mp4","link":"http://i.imgur.com/1aD2tdR.gif","looping":true},{"id":"7UzUF79","title":"Title","description":"Description","datetime":1425872641,"type":"image/gif","animated":true,"width":160,"height":120,"size":146703,"views":785,"bandwidth":115161855,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/7UzUF79.gifv","webm":"http://i.imgur.com/7UzUF79.webm","mp4":"http://i.imgur.com/7UzUF79.mp4","link":"http://i.imgur.com/7UzUF79.gif","looping":true},{"id":"3PKeSiW","title":"Title","description":"Description","datetime":1425872642,"type":"image/gif","animated":true,"width":160,"height":120,"size":136914,"views":753,"bandwidth":103096242,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/3PKeSiW.gifv","webm":"http://i.imgur.com/3PKeSiW.webm","mp4":"http://i.imgur.com/3PKeSiW.mp4","link":"http://i.imgur.com/3PKeSiW.gif","looping":true},{"id":"o3UBVgR","title":"Title","description":"Description","datetime":1425872644,"type":"image/gif","animated":true,"width":160,"height":120,"size":129046,"views":483,"bandwidth":62329218,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/o3UBVgR.gifv","webm":"http://i.imgur.com/o3UBVgR.webm","mp4":"http://i.imgur.com/o3UBVgR.mp4","link":"http://i.imgur.com/o3UBVgR.gif","looping":true},{"id":"qraDqOQ","title":"Title","description":"Description","datetime":1425872645,"type":"image/gif","animated":true,"width":160,"height":120,"size":93116,"views":466,"bandwidth":43392056,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/qraDqOQ.gifv","webm":"http://i.imgur.com/qraDqOQ.webm","mp4":"http://i.imgur.com/qraDqOQ.mp4","link":"http://i.imgur.com/qraDqOQ.gif","looping":true},{"id":"K9PuB3S","title":"Title","description":"Description","datetime":1425872647,"type":"image/gif","animated":true,"width":160,"height":120,"size":84323,"views":481,"bandwidth":40559363,"vote":null,"favorite":false,"nsfw":null,"section":null,"account_url":null,"account_id":null,"gifv":"http://i.imgur.com/K9PuB3S.gifv","webm":"http://i.imgur.com/K9PuB3S.webm","mp4":"http://i.imgur.com/K9PuB3S.mp4","link":"http://i.imgur.com/K9PuB3S.gif","looping":true},{"id":"p3whCAz","title":"Title","descriptio
03-21 21:24:26.408 8035-8035/? D/AndroidRuntime﹕ Shutting down VM
03-21 21:24:26.408 8035-8035/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.johnnymolina.nextphase, PID: 8035
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.gson.JsonElement.toString()' on a null object reference
at com.johnnymolina.nextphase.activities.Imgur$2.onCompleted(Imgur.java:116)
at com.johnnymolina.nextphase.activities.Imgur$2.onCompleted(Imgur.java:98)
at com.koushikdutta.async.future.SimpleFuture.handleCallbackUnlocked(SimpleFuture.java:107)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:141)
at com.koushikdutta.async.future.SimpleFuture.setComplete(SimpleFuture.java:128)
at com.koushikdutta.ion.IonRequestBuilder$1.run(IonRequestBuilder.java:246)
at com.koushikdutta.async.AsyncServer$RunnableWrapper.run(AsyncServer.java:57)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
03-21 21:24:26.411 6534-6864/? W/ActivityManager﹕ Force finishing activity com.johnnymolina.nextphase/.activities.Imgur
03-21 21:24:26.412 6534-6864/? W/ActivityManager﹕ Force finishing activity com.johnnymolina.nextphase/.activities.MainActivity
Ok looking at the logCat it seems that the entire JSon Object is not being printed out. Is this a limitation of what Log.v can print? Or am I getting a Null object reference because the network call isn't returning a fully complete object?
An example of what a Json object retreived from Imgur's Api looks like: https://api.imgur.com/models/album
{
"data": {
"id": "lDRB2",
"title": "Imgur Office",
"description": null,
"datetime": 1357856292,
"cover": "24nLu",
"account_url": "Alan",
"account_id": 4,
"privacy": "public",
"layout": "blog",
"views": 13780,
"link": "http://alanbox.imgur.com/a/lDRB2",
"images_count": 11,
"images": [
{
"id": "24nLu",
"title": null,
"description": null,
"datetime": 1357856352,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 855658,
"views": 135772,
"bandwidth": 116174397976,
"link": "http://i.imgur.com/24nLu.jpg"
},
{
"id": "Ziz25",
"title": null,
"description": null,
"datetime": 1357856394,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 919391,
"views": 135493,
"bandwidth": 124571044763,
"link": "http://i.imgur.com/Ziz25.jpg"
},
{
"id": "9tzW6",
"title": null,
"description": null,
"datetime": 1357856385,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 655028,
"views": 135063,
"bandwidth": 88470046764,
"link": "http://i.imgur.com/9tzW6.jpg"
},
{
"id": "dFg5u",
"title": null,
"description": null,
"datetime": 1357856378,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 812738,
"views": 134704,
"bandwidth": 109479059552,
"link": "http://i.imgur.com/dFg5u.jpg"
},
{
"id": "oknLx",
"title": null,
"description": null,
"datetime": 1357856338,
"type": "image/jpeg",
"animated": false,
"width": 1749,
"height": 2332,
"size": 717324,
"views": 32938,
"bandwidth": 23627217912,
"link": "http://i.imgur.com/oknLx.jpg"
},
{
"id": "OL6tC",
"title": null,
"description": null,
"datetime": 1357856321,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 1443262,
"views": 32346,
"bandwidth": 46683752652,
"link": "http://i.imgur.com/OL6tC.jpg"
},
{
"id": "cJ9cm",
"title": null,
"description": null,
"datetime": 1357856330,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 544702,
"views": 31829,
"bandwidth": 17337319958,
"link": "http://i.imgur.com/cJ9cm.jpg"
},
{
"id": "7BtPN",
"title": null,
"description": null,
"datetime": 1357856369,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 844863,
"views": 31257,
"bandwidth": 26407882791,
"link": "http://i.imgur.com/7BtPN.jpg"
},
{
"id": "42ib8",
"title": null,
"description": null,
"datetime": 1357856424,
"type": "image/jpeg",
"animated": false,
"width": 2592,
"height": 1944,
"size": 905073,
"views": 30945,
"bandwidth": 28007483985,
"link": "http://i.imgur.com/42ib8.jpg"
},
{
"id": "BbwIx",
"title": null,
"description": null,
"datetime": 1357856360,
"type": "image/jpeg",
"animated": false,
"width": 1749,
"height": 2332,
"size": 662413,
"views": 30107,
"bandwidth": 19943268191,
"link": "http://i.imgur.com/BbwIx.jpg"
},
{
"id": "x7b91",
"title": null,
"description": null,
"datetime": 1357856406,
"type": "image/jpeg",
"animated": false,
"width": 1944,
"height": 2592,
"size": 618567,
"views": 29259,
"bandwidth": 18098651853,
"link": "http://i.imgur.com/x7b91.jpg"
}
]
},
"success": true,
"status": 200
}
if you can post an example of the json response we can help you better.
However from what i can see the JsonElement "images_count" doesn't exists, and so you get the NullPointerException.
From what i can see, if i try that calls from the browser i get this json response:
{"data":{"error":"Authentication required","request":"\/3\/album\/gQxwy.json","method":"GET"},"success":false,"status":401}
It is possibile that you don't add some query parameter request from the WebService.
P.S.: To display current object/variable values you need to use breakpoints and run your application in debug mode