Spring Boot自定义JSON响应,使用不同的Get方法

huangapple go评论59阅读模式
英文:

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类(ShopDtoProductDto)以及相应的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&lt;Shops&gt; findAll(){
        return shopService.findAll();
    }

@GetMapping(&quot;/{id}&quot;)
    public Shops findById(@PathVariable(&quot;id&quot;) UUID id){
        return shopService.findOne(id);
    }

The result of find all method is as follows :

[
  {
    &quot;created_at&quot;: &quot;2023-02-16T02:28:31.545+00:00&quot;,
    &quot;updated_at&quot;: &quot;2023-02-16T02:28:31.545+00:00&quot;,
    &quot;id&quot;: &quot;d66cd6ff-8a22-4280-8b23-5d0a3ca01f93&quot;,
    &quot;name&quot;: &quot;Panda Star&quot;,
    &quot;city&quot;: &quot;Chicago&quot;,
    &quot;purpose&quot;: &quot;technology&quot;,
    &quot;products&quot;: [
      {
        &quot;created_at&quot;: &quot;2023-02-16T02:28:31.563+00:00&quot;,
        &quot;updated_at&quot;: &quot;2023-02-16T02:28:31.563+00:00&quot;,
        &quot;id&quot;: &quot;e0b1a1cd-33b4-428b-b4f5-8885428d87eb&quot;,
        &quot;name&quot;: &quot;Logitech M510 Wireless&quot;,
        &quot;description&quot;: &quot;some desc&quot;
      }
    ],
    &quot;user&quot;: {
        &quot;created_at&quot;: &quot;2023-02-13T02:28:31.563+00:00&quot;,
        &quot;updated_at&quot;: &quot;2023-02-13T02:28:31.563+00:00&quot;,
        &quot;id&quot;: &quot;f58f8016-d9be-4c9d-b4e3-632a262ceca9&quot;,
        &quot;name&quot;: &quot;user1&quot;,
        &quot;email&quot;: &quot;user1@mail.com&quot;
    }
  }
]

and for find by id:

{
  &quot;created_at&quot;: &quot;2023-02-16T02:28:31.545+00:00&quot;,
  &quot;updated_at&quot;: &quot;2023-02-16T02:28:31.545+00:00&quot;,
  &quot;id&quot;: &quot;d66cd6ff-8a22-4280-8b23-5d0a3ca01f93&quot;,
  &quot;name&quot;: &quot;string&quot;,
  &quot;city&quot;: &quot;string&quot;,
  &quot;purpose&quot;: &quot;string&quot;,
  &quot;products&quot;: [
    {
      &quot;created_at&quot;: &quot;2023-02-16T02:28:31.563+00:00&quot;,
      &quot;updated_at&quot;: &quot;2023-02-16T02:28:31.563+00:00&quot;,
      &quot;id&quot;: &quot;e0b1a1cd-33b4-428b-b4f5-8885428d87eb&quot;,
      &quot;name&quot;: &quot;string&quot;,
      &quot;description&quot;: &quot;string&quot;
    }
  ],
  &quot;user&quot;: {
        &quot;created_at&quot;: &quot;2023-02-13T02:28:31.563+00:00&quot;,
        &quot;updated_at&quot;: &quot;2023-02-13T02:28:31.563+00:00&quot;,
        &quot;id&quot;: &quot;f58f8016-d9be-4c9d-b4e3-632a262ceca9&quot;,
        &quot;name&quot;: &quot;user1&quot;,
        &quot;email&quot;: &quot;user1@mail.com&quot;
    }
}

How can I modify the method find all so that the result comes like this

[
  {
    &quot;created_at&quot;: &quot;2023-02-16T02:28:31.545+00:00&quot;,
    &quot;id&quot;: &quot;d66cd6ff-8a22-4280-8b23-5d0a3ca01f93&quot;,
    &quot;name&quot;: &quot;Panda Star&quot;,
    &quot;city&quot;: &quot;Chicago&quot;,
    &quot;products&quot;: [
      {
        &quot;id&quot;: &quot;e0b1a1cd-33b4-428b-b4f5-8885428d87eb&quot;,
        &quot;name&quot;: &quot;Logitech M510 Wireless&quot;,
      }
    ]
  }
]

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

希望对您有所帮助 Spring Boot自定义JSON响应,使用不同的Get方法

编辑:

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&lt;Product&gt; products;

    // getters and setters, or @Data annotation
}

create ShopMapper for mapping Shop to ShopVO:

@Component
public class ShopMapper {
    
    @Autowired ModelMapper modelMapper;

    public List&lt;ShopVO&gt; toVO(List&lt;Shop&gt; shops){
        List&lt;ShopVO&gt; vos = new ArrayList&lt;&gt;();
        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&lt;ShopVO&gt; findAll() {
    return shopMapper.toVO(shopRepo.findAll());
}

@Override
public Shop findOne(UUID id) {
    return shopRepo.getReferenceById(id);
}

Hope it helps Spring Boot自定义JSON响应,使用不同的Get方法

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&lt;ShopsDto&gt; 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&lt;Shops&gt;{
  List&lt;ShopsProduct&gt; findAll();
}

for better understanding you can see this link

huangapple
  • 本文由 发表于 2023年3月1日 12:37:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599617.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定