starter restresource repositoryrestresource excerptprojection example data custom java spring spring-mvc spring-data spring-data-rest

java - restresource - Cómo asignar la Página<ObjectEntity> a la Página<ObjectDTO> en spring-data-rest



spring data rest custom controller (6)

Cuando llego a la base de datos con PagingAndSortingRepository.findAll(Pageable) obtengo la Page<ObjectEntity> . Sin embargo, quiero exponer los DTO al cliente y no a las entidades. Puedo crear DTO simplemente inyectando una entidad en su constructor, pero ¿cómo asigno las entidades en el objeto Page a los DTO? Según la documentación de Spring, Page proporciona operaciones de solo lectura.

Además, Page.map no es posible, ya que no tenemos soporte para Java 8. ¿Cómo crear la nueva página con objetos asignados manualmente?


Aún puedes usar el Page.map sin las expresiones lambda:

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; } });


Al final, no devolverá la página a los usuarios, sino una lista de ObjectDTO, con los detalles de la página en el encabezado, por lo que esta sería mi solución.

ObjectService

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

ObjectResource / rest (el punto final expuesto)

@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); }

La razón para usar esto es para que no necesite duplicar los detalles de la página para ObjectEntity y DTO. Es clave tener en cuenta que una página contiene lo siguiente:

  • número de página
  • tamaño de página
  • numberOfElements
  • contenido

El contenido es la lista de objetos devueltos y es lo único que debe asignarse a DTO.


Aquí está mi solución, gracias a @Ali Dehghani

private Page<ObjectDTO> mapEntityPageIntoDTOPage(Page<ObjectEntity> objectEntityPage) { return objectEntityPage.map(new Converter<ObjectEntity, ObjectDTO>() { public ObjectDTO convert(ObjectEntity objectEntity) { return new ObjectDTO(objectEntity, httpSession); } }); }


En Spring Data 2, el método de mapa de página toma una función en lugar de un convertidor, pero sigue funcionando básicamente de la misma manera que lo describió @Ali Dehghani.

Utilizando la función:

Page<ObjectEntity> entities = objectEntityRepository.findAll(pageable); Page<ObjectDto> dtoPage = entities.map(new Function<ObjectEntity, ObjectDto>() { @Override public ObjectDto apply(ObjectEntity entity) { ObjectDto dto = new ObjectDto(); // Conversion logic return dto; } });


Puedes usar Page.map simplemente haciendo esto:

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; }


Y en java8:

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

Donde fromEntity es un método estático en ObjectDto que contiene la lógica de conversión.