如何操作 RestTemplate 获取的 JSON 响应来设置 DTO 对象?

发布于 2025-01-11 13:04:08 字数 2043 浏览 0 评论 0原文

我正在开发 Spring Boot 应用程序,但遇到以下问题。我必须从 REST 调用检索到的 JSON 输出中设置简单 DTO 对象的值。

基本上我调用这个GET API:https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=eur

如您所见,它返回一个 JSON 响应,例如这样:

{
    "ethereum": {
        "eur": 2509.13
    }
}

所以我有这个 CoingeckoPriceDTO 类:

@Getter

@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CoingeckoPriceDTO {
    
    String coin;
    BigDecimal price;
    
}

然后我有这个服务方法:

@Service
@Log
public class CoingeckoInfoServiceImpl implements CoingeckoInfoService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    String coinPriceApiUrl = "https://api.coingecko.com/api/v3/simple/price?ids={coinName}&vs_currencies={targetCurrency}";
    
    
    @Override
    public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) {
        
        CoingeckoPriceDTO result = new CoingeckoPriceDTO();
        
        String completeUrl = this.coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
        
        log.info("completeUrl: " + completeUrl);
        
        String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
        
        log.info("responseStr: " + responseStr);
        
        
        return result;
    }
    
}

它只需通过 REST 模板执行调用,然后将其打印为字符串,然后事实上,它将包含预期 JSON 响应的字符串打印为字符串:

responseStr: {"ethereum":{"eur":2499.04}}

现在我的问题是将这些值放入前面的 CoingeckoPriceDTO 字段中。我认为我需要进行一些 JSON 操作才能做到这一点:

特别是我必须使用返回的 JSON 检索到的 ethereum 字符串来设置我的 DTO String coin 字段(注意这不是字段值,而是字段名称,我不知道如何保留它并将其放入我的 DTO 对象字段中。然后,我必须使用 JSON 中的 eur 值设置 DTO BigDecimal Price 字段。

我怎样才能实现这样的行为?

I am working on a Spring Boot application and I have the following problem. I have to set values of a simple DTO object from the JSON output retrieved from a REST call.

Basically I am calling this GET API: https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=eur

As you can see it return a JSON response like this:

{
    "ethereum": {
        "eur": 2509.13
    }
}

So I have this CoingeckoPriceDTO class:

@Getter

@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CoingeckoPriceDTO {
    
    String coin;
    BigDecimal price;
    
}

And then I have this service method:

@Service
@Log
public class CoingeckoInfoServiceImpl implements CoingeckoInfoService {
    
    @Autowired
    private RestTemplate restTemplate;
    
    String coinPriceApiUrl = "https://api.coingecko.com/api/v3/simple/price?ids={coinName}&vs_currencies={targetCurrency}";
    
    
    @Override
    public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) {
        
        CoingeckoPriceDTO result = new CoingeckoPriceDTO();
        
        String completeUrl = this.coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
        
        log.info("completeUrl: " + completeUrl);
        
        String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
        
        log.info("responseStr: " + responseStr);
        
        
        return result;
    }
    
}

It simply perform the call via REST template then it print it as a string, and infact it print this string containing the expected JSON response as string:

responseStr: {"ethereum":{"eur":2499.04}}

Now my problem is to put these values into the previous CoingeckoPriceDTO fields. I think that I need to do some JSON manipulation to do it:

In particular I have to set my DTO String coin field with the ethereum string retrieved by the returned JSON (note that this is not the field value but it is the field name. I have no idea how to keep it and put it into my DTO object field). Then I have to set my DTO BigDecimal price field with the eur value in the JSON.

How can I implement a behavior like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沫尐诺 2025-01-18 13:04:09

尝试将您的类更改为如下所示:

   public class CoingeckoPriceDTO {

        private String coin;

        @JsonAlias({"eur", "dol", "sek", "etc"})
        private BigDecimal price;

        public String getCoin() {
            return coin;
        }

        public void setCoin(String coin) {
            this.coin = coin;
        }

        public BigDecimal getPrice() {
            return price;
        }

        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    }

将您打算包含的任何货币添加到@JsonAlias。

继续做这样的事情:

public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) throws JsonProcessingException {
    String completeUrl = coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
    String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
    JSONObject jsonObject = new JSONObject(responseStr);
    responseStr = jsonObject.getString("ethereum");

    ObjectMapper mapper = new ObjectMapper();
    CoingeckoPriceDTO result = mapper.readValue(responseStr, CoingeckoPriceDTO.class);

    result.setCoint(targetCurrency);

    return result;
}

我还没有运行代码来看看它是否真的有效,但如果需要,您可以进行调整。

Give it a try to change your class to something like this:

   public class CoingeckoPriceDTO {

        private String coin;

        @JsonAlias({"eur", "dol", "sek", "etc"})
        private BigDecimal price;

        public String getCoin() {
            return coin;
        }

        public void setCoin(String coin) {
            this.coin = coin;
        }

        public BigDecimal getPrice() {
            return price;
        }

        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    }

Add to the @JsonAlias any currencies you intend to include.

And proceed to doing something like this:

public CoingeckoPriceDTO getCoinPrice(String coinName, String targetCurrency) throws JsonProcessingException {
    String completeUrl = coinPriceApiUrl.replace("{coinName}", coinName).replace("{targetCurrency}", targetCurrency);
    String responseStr = this.restTemplate.getForObject(completeUrl, String.class);
    JSONObject jsonObject = new JSONObject(responseStr);
    responseStr = jsonObject.getString("ethereum");

    ObjectMapper mapper = new ObjectMapper();
    CoingeckoPriceDTO result = mapper.readValue(responseStr, CoingeckoPriceDTO.class);

    result.setCoint(targetCurrency);

    return result;
}

I haven't run the code to see if it actually works, but you may make your adjustments if needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文