How to map Page to Page in spring-data-rest

后端 未结 9 1638
太阳男子
太阳男子 2021-01-30 12:37

When I hit the database with PagingAndSortingRepository.findAll(Pageable) I get Page. However, I want to expose DTO\'s to the clien

相关标签:
9条回答
  • 2021-01-30 13:12

    And in java8:

    Page<ObjectDto> entities = 
     objectEntityRepository.findAll(pageable)
     .map(ObjectDto::fromEntity);
    

    Where fromEntity is a static method on ObjectDto that contains the conversion logic.

    0 讨论(0)
  • 2021-01-30 13:15

    use lambda expression is more convenient

    Page<ObjectDto> dto=objectRepository.findAll(pageable).map((object -> DozerBeanMapperBuilder.buildDefault().map(object, ObjectDto.class)));
    
    0 讨论(0)
  • 2021-01-30 13:16

    At the end, you will not return the Page to the users, but a list of ObjectDTO, with the Page details at the header, so this would be my solution.

    ObjectService

    public Page<ObjectEntity> findAll (Pageable pageable){
      //logic goes here.
      Page<ObjectEntity> page = objectRepository.findAll(pageable);
      return page;
    } 
    

    ObjectResource / rest (the exposed endpoint)

    @GetMapping
    public ResponseEntity<List<ObjectDTO>> findAll (Pageable pageable){
      Page<ObjectEntity> page = objectServiceService.findAll(pageable);
    
      HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "your-endpoint-here");
    
      return new ResponseEntity<>(objectMapper.toDto(page.getContent()), headers, HttpStatus.OK);
    }
    

    The reason for using this is so that you don't need to duplicate the page details for ObjectEntity and DTO. It is key to note that a page contains the following:

    • page number
    • pageSize
    • numberOfElements
    • content

    The content is the list of objects returned, and is the only thing that needs to be mapped to DTO.

    0 讨论(0)
  • 2021-01-30 13:18

    You can still use the Page.map without lambda expressions:

    Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable);
    Page<ObjectDto> dtoPage = entities.map(new Converter<ObjectEntity, ObjectDto>() {
        @Override
        public ObjectDto convert(ObjectEntity entity) {
            ObjectDto dto = new ObjectDto();
            // Conversion logic
    
            return dto;
        }
    });
    
    0 讨论(0)
  • 2021-01-30 13:19

    You can use Page.map by simply doing this:

    public Page<ObjectDto> toPageObjectDto(Page<Object> objects) {
        Page<ObjectDto> dtos  = objects.map(this::convertToObjectDto);
        return dtos;
    }
    
    private ObjectDto convertToObjectDto(Object o) {
        ObjectDto dto = new ObjectDto();
        //conversion here
        return dto;
    }
    
    0 讨论(0)
  • 2021-01-30 13:24

    I am created and using solution with model mapper, generics and lambdas for common usage.

    /**
     * Maps the Page {@code entities} of <code>T</code> type which have to be mapped as input to {@code dtoClass} Page
     * of mapped object with <code>D</code> type.
     *
     * @param <D> - type of objects in result page
     * @param <T> - type of entity in <code>entityPage</code>
     * @param entities - page of entities that needs to be mapped
     * @param dtoClass - class of result page element
     * @return page - mapped page with objects of type <code>D</code>.
     * @NB <code>dtoClass</code> must has NoArgsConstructor!
     */
    public <D, T> Page<D> mapEntityPageIntoDtoPage(Page<T> entities, Class<D> dtoClass) {
        return entities.map(objectEntity -> modelMapper.map(objectEntity, dtoClass));
    } 
    

    This is exactly the case which you need (and I think common case for wide range of other cases).

    You already have the data obtained from repository (same is with service) on this way:

    Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable);
    

    Everything what you need for conversion is to call this method on this way:

    Page<ObjectDto> dtoPage = mapEntityPageIntoDtoPage(entities, ObjectDto.class);
    

    @Tip: You can use this method from util class, and it can be reused for all entity/dto in Page conversions on services and controllers according to your architecture.

    Example:

    Page<ObjectDto> dtoPage = mapperUtil.mapEntityPageIntoDtoPage(entities, ObjectDto.class);
    
    0 讨论(0)
提交回复
热议问题