Chefk5
Chefk5

Reputation: 469

Why not receiving pageable details in spring boot?

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

Answers (2)

Andrew
Andrew

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

Fernix
Fernix

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

Related Questions