英文:
Spring Boot Custom JSON response with different Get Method
问题
你可以修改findAll
方法来实现你的需求。你需要创建一个新的数据传输对象(DTO),以便返回你所需的数据结构。以下是示例代码:
@GetMapping
public List<ShopDto> findAll() {
List<Shop> shops = shopService.findAll();
List<ShopDto> shopDtos = new ArrayList<>();
for (Shop shop : shops) {
ShopDto shopDto = new ShopDto();
shopDto.setCreatedAt(shop.getCreatedAt());
shopDto.setId(shop.getId());
shopDto.setName(shop.getName());
shopDto.setCity(shop.getCity());
List<Product> products = shop.getProducts();
List<ProductDto> productDtos = new ArrayList<>();
for (Product product : products) {
ProductDto productDto = new ProductDto();
productDto.setId(product.getId());
productDto.setName(product.getName());
productDtos.add(productDto);
}
shopDto.setProducts(productDtos);
shopDtos.add(shopDto);
}
return shopDtos;
}
在这个示例中,我们创建了一个名为ShopDto
的新DTO,它包含了你所需的字段。然后,在findAll
方法中,我们从数据库中获取Shop
对象并将其映射到ShopDto
对象,只包含所需的字段。这样,你可以获得期望的响应,而findById
方法可以继续返回完整的数据。
注意:你需要创建相应的DTO类(ShopDto
和ProductDto
)以及相应的setter和getter方法来使上述代码工作。
英文:
I developed a spring boot application, in the controller I have a method that returns a list of shops and one of the shop. I want to make different response for different get method, since when you use find all method, not all of the data is necessary, especially to avoid redundancy of data. But, when you use find by id method, you need all of the data with all the relation.
Below is my controller
@GetMapping
public List<Shops> findAll(){
return shopService.findAll();
}
@GetMapping("/{id}")
public Shops findById(@PathVariable("id") UUID id){
return shopService.findOne(id);
}
The result of find all method is as follows :
[
{
"created_at": "2023-02-16T02:28:31.545+00:00",
"updated_at": "2023-02-16T02:28:31.545+00:00",
"id": "d66cd6ff-8a22-4280-8b23-5d0a3ca01f93",
"name": "Panda Star",
"city": "Chicago",
"purpose": "technology",
"products": [
{
"created_at": "2023-02-16T02:28:31.563+00:00",
"updated_at": "2023-02-16T02:28:31.563+00:00",
"id": "e0b1a1cd-33b4-428b-b4f5-8885428d87eb",
"name": "Logitech M510 Wireless",
"description": "some desc"
}
],
"user": {
"created_at": "2023-02-13T02:28:31.563+00:00",
"updated_at": "2023-02-13T02:28:31.563+00:00",
"id": "f58f8016-d9be-4c9d-b4e3-632a262ceca9",
"name": "user1",
"email": "user1@mail.com"
}
}
]
and for find by id:
{
"created_at": "2023-02-16T02:28:31.545+00:00",
"updated_at": "2023-02-16T02:28:31.545+00:00",
"id": "d66cd6ff-8a22-4280-8b23-5d0a3ca01f93",
"name": "string",
"city": "string",
"purpose": "string",
"products": [
{
"created_at": "2023-02-16T02:28:31.563+00:00",
"updated_at": "2023-02-16T02:28:31.563+00:00",
"id": "e0b1a1cd-33b4-428b-b4f5-8885428d87eb",
"name": "string",
"description": "string"
}
],
"user": {
"created_at": "2023-02-13T02:28:31.563+00:00",
"updated_at": "2023-02-13T02:28:31.563+00:00",
"id": "f58f8016-d9be-4c9d-b4e3-632a262ceca9",
"name": "user1",
"email": "user1@mail.com"
}
}
How can I modify the method find all so that the result comes like this
[
{
"created_at": "2023-02-16T02:28:31.545+00:00",
"id": "d66cd6ff-8a22-4280-8b23-5d0a3ca01f93",
"name": "Panda Star",
"city": "Chicago",
"products": [
{
"id": "e0b1a1cd-33b4-428b-b4f5-8885428d87eb",
"name": "Logitech M510 Wireless",
}
]
}
]
but, still keeping the find by id result as it is?
答案1
得分: 1
我建议在您的服务层中使用mapper
来解决您的问题。
定义您想要用于视图的ShopVO
:
public class ShopVO {
private Date createdAt;
private UUID id;
private String name;
private String city;
private List<Product> products;
// getters and setters, or @Data annotation
}
创建ShopMapper
来将Shop
映射到ShopVO
:
@Component
public class ShopMapper {
@Autowired
ModelMapper modelMapper;
public List<ShopVO> toVO(List<Shop> shops){
List<ShopVO> vos = new ArrayList<>();
for(Shop shop : shops){
vos add(toVO(shop));
}
return vos;
}
public ShopVO toVO(Shop shop){
return modelMapper.map(shop, ShopVO.class);
}
}
在ShopService
中:
@Override
public List<ShopVO> findAll() {
return shopMapper.toVO(shopRepo.findAll());
}
@Override
public Shop findOne(UUID id) {
return shopRepo.getReferenceById(id);
}
希望对您有所帮助
编辑:
ModelMapper
的Bean配置:
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setAmbiguityIgnored(true);
return modelMapper;
}
英文:
I would suggest using mapper in your service layer for your issue.
Defining ShopVO
which you want for view:
public class ShopVO {
private Date createdAt;
private UUID id;
private String name;
private String city;
private List<Product> products;
// getters and setters, or @Data annotation
}
create ShopMapper
for mapping Shop
to ShopVO
:
@Component
public class ShopMapper {
@Autowired ModelMapper modelMapper;
public List<ShopVO> toVO(List<Shop> shops){
List<ShopVO> vos = new ArrayList<>();
for(Shop shop : shops){
vos.add(toVO(shop));
}
return vos;
}
public ShopVO toVO(Shop shop){
return modelMapper.map(shop, ShopVO.class);
}
}
In ShopService
:
@Override
public List<ShopVO> findAll() {
return shopMapper.toVO(shopRepo.findAll());
}
@Override
public Shop findOne(UUID id) {
return shopRepo.getReferenceById(id);
}
Hope it helps
EDIT:
Bean for ModelMapper
:
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setAmbiguityIgnored(true);
return modelMapper;
}
答案2
得分: 0
使用DTO类来实现你需要的功能:
import lombok.Data;
@Data
class ShopsDto{
Date created_at;
String id;
String name;
String city;
ProductDto products;
}
然后将你的实体对象转换为DTO对象。对于这项工作,你可以手动完成,也可以使用一些类似于 mapstruct
这样的库,它与 lombok
集成得很好。
private ShopConverter converter;
@GetMapping
public List<ShopsDto> findAll(){
return converter.toDto(shopService.findAll());
}
另一种方法是使用Spring Data Projection,接口指定你选择的字段:
class ShopsProduct{
Date getCreated_at();
String getId();
String getName();
String getCity();
Product getProducts();
}
class ShopRepository extends JpaRepository<Shops>{
List<ShopsProduct> findAll();
}
为了更好地理解,你可以查看这个链接:link
英文:
you can do one of the samples:
using DTO class that what you need:
import lombok.Data;
@Data
class ShopsDto{
Date created_at;
String id;
String name;
String city;
ProductDto products;
}
and convert your entity object to DTO object. for this work you can do it manually and using some library for that like mapstruct
that It have integrated with lombok
too.
private ShopConverter converter;
@GetMapping
public List<ShopsDto> findAll(){
return converter.toDto(shopService.findAll());
}
in another way you can use spring data Projection that Interface specify
what fields you selected:
class ShopsProduct{
Date getCreated_at();
String getId();
String getName();
String getCity();
Product getProducts();
}
class ShopRepository extend JpaRepository<Shops>{
List<ShopsProduct> findAll();
}
for better understanding you can see this link
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论