将JSON对象名称 - 值对反序列化为数组的元素

时间:2017-01-06 15:56:39

标签: java json jackson

我试图将后续字符串转换为对象,

{   
    "base":"TRY",
    "date":"2017-01-06",
    "rates":{
       "EUR":0.37679,
       "USD":0.51059,
       "BRL":0.88513,
       "CAD":0.36651,
       ...
    }
}

我知道,如果我创建一个包含所有费率为Double属性的对象,我将能够将该对象转换为对象。但是我希望费率在下面的数组中。如何创建convertedJsonObjectArrayList。提前谢谢。

List<Rate> rates = convertedJsonObjectArrayList;

class Rate{
    String name; //EUR
    Double value; //0.37679

}

5 个答案:

答案 0 :(得分:2)

这假定您确保在与名称"rates"相关联的JSON对象中包含可以作为List进行解析的内容。

定义自定义反序列化器以将名称 - 值标记作为对使用

class RatesJsonObjectToArray extends JsonDeserializer<List<Rate>> {
    @Override
    public List<Rate> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        List<Rate> rates = new ArrayList<>();
        // consume two tokens at a time, a name and a value
        for (;;) {
            String name = p.nextFieldName();
            if (name == null) {
                break; // no more input
            }
            JsonToken doubleValueToken = p.nextValue();
            if (doubleValueToken != JsonToken.VALUE_NUMBER_FLOAT) { // there's also VALUE_NUMBER_INT for more flexibility
                throw new JsonParseException("Expected a numeric value.");
            }
            double value = p.getDoubleValue();
            rates.add(new Rate(name, value));
        }
        return rates;
    }
}

然后使用此rates

为您的JsonDeserializer字段/ setter添加注释
@JsonProperty
@JsonDeserialize(using = RatesJsonObjectToArray.class)
private List<Rate> rates;

答案 1 :(得分:1)

你可以想象并写一个custom deserializer

但是,如果您不介意更加快速和肮脏,您可以反序列化为地图,并明确转换为您的首选结构:

    String ratesAsJson = "{ \"EUR\" : 0.2, \"USD\":1.0 }";
    ObjectMapper objectMapper = new ObjectMapper();
    TypeReference<Map<String, Double>> typeRef = new TypeReference<Map<String, Double>>() {};

    Map<String, Double> map = objectMapper.readValue(ratesAsJson, typeRef);
    List<Rate> list = map.entrySet().stream()
            .map(entry -> new Rate(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());

(我假设Rate类上有一个2-arg构造函数。)

如果您编写自定义反序列化器,它将具有与上述代码非常相似的代码。

我使用了一个流和map()。您可以使用for循环,但是嘿,这是2017年!

答案 2 :(得分:0)

如果要将货币对象(json)转换为数组(java)您不能使用序列化(gson / jaxb),您需要解析(JsonParser)json并自行进行转换

答案 3 :(得分:0)

这是我的解决方案;

ObjectMapper mapper = new ObjectMapper();
CurrencyServiceResponse currencyResp = 
    mapper.readValue(jsonStr,new TypeReference<CurrencyServiceResponse>(){});

currencyResp.setRates(new ArrayList<>());
for(Map.Entry<String,Double> entry: currencyResp.getRateMap().entrySet()){
            currencyResp.getRates().add(
                new CurrencyServiceResponse.Rate(entry.getKey(),entry.getValue()));
        }

转换课程

public class CurrencyServiceResponse {

    @JsonProperty("base")
    private String base;

    @JsonProperty("date")
    private Date date;

    @JsonProperty("rates")
    private Map<String,Double> rateMap;

    @JsonIgnore
    private List<Rate> rates;

    //getters&setters

    public static class Rate{

        private String name;
        private Double value;

        public Rate(String name, Double value) {
            this.name = name;
            this.value = value;
        }

        //getters&setters
    }
}

答案 4 :(得分:-1)

您可以使用GSON库。这是 Google JSON库

JsonParser jp = new JsonParser();
JsonElement root = jp.parse(YOUR_DATA);
JsonObject rootobj = root.getAsJsonObject();

访问欧元汇率的情况下,您可以使用:

Double rate_eur = rootobj.get("rates").getAsJsonObject().get("EUR").getAsDouble();

不要忘记导入课程

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

依赖

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>RELEASE</version>
</dependency>
例如

对于maven。