Quand je frappe la base de données avec PagingAndSortingRepository.findAll(Pageable)
je reçois Page<ObjectEntity>
. Cependant, je veux exposer les DTO au client et non aux entités. Je peux créer un DTO simplement en injectant une entité dans son constructeur, mais comment mapper les entités de l'objet Page sur les DTO? Selon la documentation de Spring, Page fournit des opérations en lecture seule.
De plus, Page.map n'est pas possible, car nous ne prenons pas en charge Java 8. Comment créer manuellement la nouvelle page avec des objets mappés?
Vous pouvez toujours utiliser le Page.map
sans expressions 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;
}
});
Dans Spring Data 2, la méthode de mappage de page prend une fonction au lieu d'un convertisseur, mais elle fonctionne toujours de la même manière que celle décrite par @ALi Dehghani.
Utilisation de la fonction:
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;
}
});
Voici ma solution, merci à @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);
}
});
}
Et en Java8:
Page<ObjectEntity> entities =
objectEntityRepository.findAll(pageable)
.map(ObjectDto::fromEntity);
Où fromEntity est une méthode statique sur ObjectDto qui contient la logique de conversion.
Vous pouvez utiliser Page.map en faisant simplement ceci:
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;
}
À la fin, vous ne retournerez pas la page aux utilisateurs, mais une liste d'ObjectDTO, avec les détails de la page dans l'en-tête, donc ce serait ma solution.
public Page<ObjectEntity> findAll (Pageable pageable){
//logic goes here.
Page<ObjectEntity> page = objectRepository.findAll(pageable);
return page;
}
@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 raison de cette utilisation est que vous n'avez pas besoin de dupliquer les détails de la page pour ObjectEntity et DTO. Il est essentiel de noter qu'une page contient les éléments suivants:
content est la liste des objets retournés, et est la seule chose qui doit être mappée sur DTO.