Reputation: 469
I am working in a spring boot project. I am required to return a list with pagination. Currently I can choose the page and size in parameters but i am not receiving page details like:
"last": false,
"totalElements": 20,
"totalPages": 7,
"size": 3,
"number": 0,
"sort": null,
"first": true,
"numberOfElements": 3
I am just receiving a normal response without that. I think I need to change method response type to ResponseEntity or Resources. Any ideas?
Controller:
public List<PostOutputDTO> getTopicPosts(@PathVariable("id") UUID topicId, Pageable pageable) {
return postService.getActivePosts(topicId, pageable);
Service:
public List<PostOutputDTO> getActivePosts(UUID topicId, Pageable pageable) throws AccessDeniedException {
Topic topic = topicRepo.findByIdAndDeactivatedAtIsNull(topicId).orElseThrow(() -> new EntityNotFoundException("This topic doesn't exist."));
if (topic.getType() != TopicType.GLOBAL) {
throw new AccessDeniedException("This is not a global topic.");
}
return postAssembler.toResources(postRepo.findPostsByTopicAndDeactivatedAtIsNull(topic, pageable));
}
Assembler:
@Service
public class PostAssembler extends ResourceAssemblerSupport<Post, PostOutputDTO> {
@Autowired
private ForumUserAssembler forumUserAssembler;
@Autowired
private TopicAssembler topicAssembler;
@Autowired
private ContentRepo contentRepo;
public PostAssembler() {
super(PostController.class, PostOutputDTO.class);
}
public PostOutputDTO toResource(Post post) {
return PostOutputDTO.builder()
.uuid(post.getId())
.topic(topicAssembler.toResource(post.getTopic()))
.text(contentRepo.findByPostAndDeactivatedAtIsNull(post).orElseThrow(() -> new EntityNotFoundException("This post doesn’t have content")).getText())
.createdAt(post.getCreatedAt())
.createdBy(forumUserAssembler.toResource(post.getCreatedBy()))
.build();
}
}
Repository:
@Repository
public interface TopicRepo extends JpaRepository<Topic, UUID> {
Page<Topic> findAllByTypeAndDeactivatedAtIsNull(TopicType topicType, Pageable pageable);
}
Upvotes: 1
Views: 928
Reputation: 49606
Adjust the return type to Page<PostOutputDTO>
instead of List<PostOutputDTO>
.
The easiest way to convert a List<PostOutputDTO>
to a Page<PostOutputDTO>
is
public Page<PostOutputDTO> getTopicPosts(@PathVariable("id") UUID topicId, Pageable pageable) {
return new PageImpl<>(postService.getActivePosts(topicId, pageable));
}
Update:
I still don't see the whole picture, but I hope the repository methods return Page
instances,
Page<Post> findPostsByTopicAndDeactivatedAtIsNull(...);
Page<Topic> findAllByTypeAndDeactivatedAtIsNull(...);
so the problem comes from PostAssembler#toResources
which returns a List
, which we inaccurately transform into a Page
back.
If I get you correctly, you are utilising ResourceAssemblerSupport
to map an Iterable<Post>
(more precisely, a Page<Post>
) to a List<PostOutputDTO>
.
What I am suggesting is to not use PostAssembler#toResources
and stick to PostAssembler#toResource
and Page#map
:
postRepo.findPostsByTopicAndDeactivatedAtIsNull(topic, pageable)
.map(postAssembler::toResource);
Upvotes: 3
Reputation: 371
You must return Interface Page from spring:
A page is a sublist of a list of objects. It allows gain information about the position of it in the containing.
See the example:
public Page<PostOutputDTO> getActivePosts(UUID topicId, Pageable pageable) {
Page<PostOutputDTO> list=postService.getActivePosts(topicId, pageable);
return list;
}
for more info see the reference
Upvotes: 1