我想在我的Spring Boot应用程序中处理here中描述的加密库存数据。 RESTTemplate使用Gson进行反序列化。响应数据如下:
{
"IOST": {
"EUR": 0.01147,
"USD": 0.01296
},
"XRP": {
"EUR": 0.2837,
"USD": 0.3208
},
...
}
我之前已经编写了一个自定义解串器。问题在于,这是作为键值对插入为数组的单个对象而来的。结果应该是以下对象的列表:
public class Symbol {
private Long id; // not relevant during conversion
private Date timestamp; // not relevant during conversion
private String symbol;
private Double eurPrice;
private Double usdPrice;
}
有什么想法可以做到这一点吗?
答案 0 :(得分:1)
由于对此API
的响应是动态的,并且取决于参数,因此最佳选择是在反序列化方面使用动态结构。最好的选择是Map
。您可以使用String
或enum
作为键:Currency
,Crypto
。反序列化后,您可以将Map
转换为必需的POJO
类。简单的例子:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GsonTest {
public static void main(String[] args) {
String json = "{\"IOST\": {"
+ " \"EUR\": 0.01147,"
+ " \"USD\": 0.01296"
+ " },"
+ " \"XRP\": {"
+ " \"EUR\": 0.2837,"
+ " \"USD\": 0.3208"
+ "}}";
Gson gson = new GsonBuilder().create();
Type type = new TypeToken<Map<String, Map<Currency, BigDecimal>>>() {
}.getType();
Map<String, Map<Currency, BigDecimal>> response = gson.fromJson(json, type);
List<Symbol> symbols = response.entrySet()
.stream()
.map(e -> {
Symbol symbol = new Symbol();
symbol.setSymbol(e.getKey());
symbol.setEurPrice(
e.getValue().getOrDefault(Currency.EUR, BigDecimal.ZERO).doubleValue());
symbol.setUsdPrice(
e.getValue().getOrDefault(Currency.USD, BigDecimal.ZERO).doubleValue());
return symbol;
}).collect(Collectors.toList());
System.out.println(symbols);
}
enum Currency {
EUR,
USD
}
}
上面的示例打印:
[Symbol{id=null, timestamp=null, symbol='IOST', eurPrice=0.01147, usdPrice=0.01296}, Symbol{id=null, timestamp=null, symbol='XRP', eurPrice=0.2837, usdPrice=0.3208}]
如果您要直接创建List
中的Symbol
-s,则需要实现自定义反序列化器。例如,看一下这个问题:Parsing JSON Array to Java List Using Gson
答案 1 :(得分:0)
您必须按照以下课程进行课程
CONCAT
上面是一个模型,下面是解析
public class Symbol {
private double EUR;
private double USD;
public double getEUR() {
return EUR;
}
public void setEUR(double EUR) {
this.EUR = EUR;
}
public double getUSD() {
return USD;
}
public void setUSD(double USD) {
this.USD = USD;
}
}
答案 2 :(得分:0)
Hareshs anweser不太适合100%,但它帮助我弄清楚了:
var url = "...";
var entries = new ArrayList<Symbol>();
var timestamp = Timestamp.from(Instant.now());
Symbol symbol;
ResponseEntity<JsonObject> response = restTemplate.getForEntity(url, JsonObject.class);
for (Map.Entry<String, JsonElement> entry : response.getBody().entrySet()) {
symbol = new Symbol();
symbol.setSymbol(entry.getKey());
symbol.setEurPrice(entry.getValue().getAsJsonObject().get("EUR").getAsDouble());
symbol.setUsdPrice(entry.getValue().getAsJsonObject().get("USD").getAsDouble());
symbol.setTimestamp(timestamp);
entries.add(symbol);
}
这可以解决问题。但是,如果有人找到在Gson解串器中完全完成此操作的方法,我很想听听!