Java 如何在 spring-data-rest 中将 Page<ObjectEntity> 映射到 Page<ObjectDTO>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39036771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to map Page<ObjectEntity> to Page<ObjectDTO> in spring-data-rest
提问by Tuomas Toivonen
When I hit the database with PagingAndSortingRepository.findAll(Pageable)
I get Page<ObjectEntity>
. However, I want to expose DTO's to the client and not entities. I can create DTO just by injecting entity into it's constructor, but how do I map the entities in Page object to DTO's? According to spring documentation, Page provides read-only operations.
当我点击数据库时,PagingAndSortingRepository.findAll(Pageable)
我得到Page<ObjectEntity>
. 但是,我想向客户端而不是实体公开 DTO。我可以通过将实体注入它的构造函数来创建 DTO,但是如何将 Page 对象中的实体映射到 DTO?根据 spring 文档,Page 提供只读操作。
Also, Page.map is not possibility, as we don't have support for java 8. How to create the new Page with mapped objects manually?
另外,Page.map 是不可能的,因为我们不支持 java 8。如何手动创建带有映射对象的新页面?
采纳答案by Ali Dehghani
You can still use the Page.map
without lambda expressions:
您仍然可以使用Page.map
without 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;
}
});
回答by Tuomas Toivonen
Here is my solution, thanks to @Ali Dehghani
这是我的解决方案,感谢@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);
}
});
}
回答by Mustafa
And in java8:
在java8中:
Page<ObjectDto> entities =
objectEntityRepository.findAll(pageable)
.map(ObjectDto::fromEntity);
Where fromEntity is a static method on ObjectDto that contains the conversion logic.
其中 fromEntity 是 ObjectDto 上包含转换逻辑的静态方法。
回答by JayL
In Spring Data 2, the Page map method takes a Function instead of a Converter, but it still works basically the same as @Ali Dehghani described.
在 Spring Data 2 中,Page map 方法采用 Function 而不是 Converter,但它的工作方式与 @Ali Dehghani 描述的基本相同。
Using Function:
使用功能:
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;
}
});
回答by Peter Mutisya
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.
最后,您不会将页面返回给用户,而是返回一个 ObjectDTO 列表,页面详细信息位于标题处,因此这将是我的解决方案。
ObjectService
对象服务
public Page<ObjectEntity> findAll (Pageable pageable){
//logic goes here.
Page<ObjectEntity> page = objectRepository.findAll(pageable);
return page;
}
ObjectResource / rest (the exposed endpoint)
ObjectResource / rest(暴露的端点)
@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:
使用它的原因是您不需要复制 ObjectEntity 和 DTO 的页面详细信息。需要注意的是,页面包含以下内容:
- page number
- pageSize
- numberOfElements
- content
- 页码
- 页面大小
- 元素数
- 内容
The contentis the list of objects returned, and is the only thing that needs to be mapped to DTO.
该内容是返回的对象列表中,并且是需要被映射到DTO的唯一的事情。
回答by Ilias Mentz
You can use Page.map by simply doing this:
您可以通过简单地执行以下操作来使用 Page.map:
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;
}
回答by Bosko Mijin
I am created and using solution with model mapper, generics and lambdas for common usage.
我创建并使用带有模型映射器、泛型和 lambda 的解决方案以供常见用途。
/**
* 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.
@提示:您可以在 util 类中使用此方法,并且可以根据您的架构在服务和控制器上的页面转换中将其重用于所有实体/dto。
Example:
例子:
Page<ObjectDto> dtoPage = mapperUtil.mapEntityPageIntoDtoPage(entities, ObjectDto.class);
回答by Evol Rof
use lambda expression is more convenient
使用 lambda 表达式更方便
Page<ObjectDto> dto=objectRepository.findAll(pageable).map((object -> DozerBeanMapperBuilder.buildDefault().map(object, ObjectDto.class)));
回答by Biswajit Dutta
This works correctly in Spring 2.0 -
这在 Spring 2.0 中正常工作 -
@Override
public Page<BookDto> getBooksByAuthor(String authorId, Pageable pageable) {
Page<BookEntity> bookEntity = iBookRepository.findByAuthorId(authorId, pageable);
return bookEntity.map(new Function<BookEntity, BookDto>() {
@Override
public BookDto apply(BookEntity t) {
return new ModelMapper().map(t, BookDto.class);
}
});
}
The converter is no longer supported in Page type for Spring 2.0. Also, the Function should be used from java.util.function.Function.
Spring 2.0 的页面类型不再支持转换器。此外,函数应该从 java.util.function.Function 使用。