javaspring-bootrestcontroller

How to print nested objects parameters in spring boot when using GET method?


Don't know if I managed to phrase if correctly, but basicaly:

**What I want:**
[
 {
  "fruit1": "x",
  "fruit2": "y",
  "fruit3" "z",
  "wallet": {
    "item1": "a",
    "item2": "b",
    "item3": "c"}
 }
]

**What I'm getting:**
[
 {
  "fruit1": "x",
  "fruit2": "y",
  "fruit3" "z",
  "wallet": {}
 }
]

My code currently is like this:

Basket model

@Data
@Entity
@Table(name = "BASKETS")
 public class Basket{
  @Id
  private String owner;
  private String fruit1;
  private String fruit2;
  private String fruit3;
  @Embedded
  private Wallet wallet;
}

Wallet model

@Embeddable
public class Wallet{
  private String item1;
  private String item2;
  private String item3;
}

Basket Service

@Service
public class BasketService{

  @Autowired
  private BasketRepository basketRepo;

  public List<Basket> find(){
    return basketRepo.findAll();
  }
}

Basket Controller

@RestController
@RequestMapping(value = "/baskets")
public class BasketController{

 @Autowired
 private BasketRepository basketRepo;

 @Autowired
 private BasketService basketService;

 @Autowired
 private ModdelMapper mapper;

  @GetMapping
    public ResponseEntity<List<BasketResponse>> find(){
        var baskets = basketService.find();
        var result = new ArrayList<BasketResponse>();
        for (Basket basket : baskets){
            var basketDTO = mapper.map(basket, BasketResponse.class);
            result.add(basketDTO);
        }
        return ResponseEntity.ok(result);
    }
}

I don't know what exactly to change, tried to search for a solution, but probably I don't know how to search for this specifically.


Solution

  • I think you should create a custom DTO class that represents the structure you want in the response. You can then manually map the data from the Basket and Wallet objects to this DTO.

     @Data
    public class BasketResponse {
        private String fruit1;
        private String fruit2;
        private String fruit3;
        private WalletResponse wallet;
    }
    
    @Data
    public class WalletResponse {
        private String item1;
        private String item2;
        private String item3;
    }
    
    @Service
    public class BasketService {
        @Autowired
        private BasketRepository basketRepo;
    
        public List<BasketResponse> find() {
            List<Basket> baskets = basketRepo.findAll();
            return baskets.stream().map(this::mapToResponse).collect(Collectors.toList());
        }
    
        private BasketResponse mapToResponse(Basket basket) {
            BasketResponse basketResponse = new BasketResponse();
            basketResponse.setFruit1(basket.getFruit1());
            basketResponse.setFruit2(basket.getFruit2());
            basketResponse.setFruit3(basket.getFruit3());
    
            Wallet wallet = basket.getWallet();
            if (wallet != null) {
                WalletResponse walletResponse = new WalletResponse();
                walletResponse.setItem1(wallet.getItem1());
                walletResponse.setItem2(wallet.getItem2());
                walletResponse.setItem3(wallet.getItem3());
                basketResponse.setWallet(walletResponse);
            }
    
            return basketResponse;
        }
    }
    
    
    @RestController
    @RequestMapping(value = "/baskets")
    public class BasketController {
        @Autowired
        private BasketService basketService;
    
        @GetMapping
        public ResponseEntity<List<BasketResponse>> find() {
            List<BasketResponse> baskets = basketService.find();
            return ResponseEntity.ok(baskets);
        }
    }