I was trying to call data from Directus API, and return certain data in JSON Format on my localhost.
I'm working on a project where we need to build an API layer.
My code:
public String findAllPersons(HttpServletResponse response, String showFields) throws IOException{
try {
// Call to the database (this part is normally not a problem
String url = "https://cuxhsjf3.directus.app/items/blog";
PersonRoot personRoot = template.getForObject(url, PersonRoot.class);
// I used the Objectmapper, since I'm going from normal data to Json.
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode personsObject = objectMapper.createObjectNode();
ArrayNode persons = objectMapper.createArrayNode();
// The array is going to loop through all the data objects from the database
for (int i = 0; i < personRoot.data.toArray().length; i++) {
// I put person objects into an array, and I return this array.
personsObject.put("id", personRoot.data.get(i).id);
personsObject.put("firstName", personRoot.data.get(i).firstName);
persons.add(personsObject);
System.out.println(persons);
}
String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(persons);
return json;
}
// The 'catch' was omitted as not related to the issue
Expected result:
{
"id": "050469ed-0501-4506-9951-794b41bf7e7f",
"firstName": "Elias"
},
{
"id": "0bfb52f7-3656-4202-8c24-2b63eaeca6a9",
"firstName": "Mathias"
},
{
"id": "3145fb95-afd7-4bc4-a62e-a8622b301db2",
"firstName": "Brent"
},
{
"id": "5b93c9b1-4bd1-4aa5-a5ca-d46e849cc58f",
"firstName": "Jef "
},
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
}
}
The output I'm getting:
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
},
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
},
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
},
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
},
{
"id": "cb3d5d02-6b87-4aa1-b817-17550b3cf03c",
"firstName": "Jan"
}
}
As @markspace has pointed out in the comments, you're repeatedly adding the reference to the same ObjectNode
into the same JsonArray
. When you're modifying this single object, all the elements in the get updated, and what you're getting is data of the very last person replicated multiple time.
You need to move creation of the ObjectNode
into the loop, so that a new node would be instantiated for each person:
for (int i = 0; i < personRoot.data.toArray().length; i++) {
ObjectNode personsObject = objectMapper.createObjectNode(); // move object-creation inside the loop
personsObject.put(...);
personsObject.put(...);
persons.add(personsObject);
}
Encapsulation in your custom class PersonRoot
is broken. In Java, we use access modifier like protected
and private
to hide and protect the data within a class instance. And class is supposed to provide behavior which allow interacting with the state of its instances instead of exposing the instance variables directly ( getters are the simplest example of such behavior ). This might look alien to you, if previously you were working with languages like JavaScript, but Encapsulation is one of the crucial parts of Object-oriented programming, and it's a common practice in Java to design classes in such a way so that their data is properly encapsulated.
You might also want to learn about one of the GRASP design-patterns, namely The information expert pattern . Which states that an object containing the data should be provided with behavior that facilitates interaction with the data (it's not the responsibility of the code that make use of this object).
Ie instead of doing this: personRoot.data.toArray().length
you can introduce length()
method in the PersonRoot
class. And instead of writing personRoot.data.get(i)
there could be a method like PersonRoot.getPerson(int index)
.
You can also make PersonRoot
implement Iterable
interface, so that it could be used as a source of data within an enhanced for
-loop.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.