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

Java 将JSON对象名称-值对反序列化为数组元素,java,json,jackson,Java,Json,Jackson,我正在尝试将以下字符串转换为对象 { "base":"TRY", "date":"2017-01-06", "rates":{ "EUR":0.37679, "USD":0.51059, "BRL":0.88513, "CAD":0.36651, ... } } 我知道,如果我创建一个包含所有速率的对象作为Double属性,我将能够将该对象转换为一个对象。但我希望利率是一个数组,如下所示

我正在尝试将以下字符串转换为对象

{   
    "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

}
List rates=convertedJsonObjectArrayList;
等级率{
字符串名称;//欧元
双值;//0.37679
}

您可以使用GSON库。这是谷歌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>
和依赖关系:

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>

com.google.code.gson
格森
释放

以maven为例。

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

您可以想象并编写一个

但是,如果您不介意更快速、更脏一点,您可以将其反序列化为映射,并显式转换为首选结构:

    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());
String ratesAsJson=“{\'EUR\':0.2,\'USD\':1.0}”;
ObjectMapper ObjectMapper=新的ObjectMapper();
TypeReference typeRef=新的TypeReference(){};
Map Map=objectMapper.readValue(ratesAsJson,typeRef);
List List=map.entrySet().stream()
.map(entry->newrate(entry.getKey(),entry.getValue())
.collect(Collectors.toList());
(我假设
Rate
类上有一个2-arg构造函数)

如果您编写一个自定义反序列化程序,它将包含与上面非常相似的代码


我使用了一个流和
map()
。你可以使用
进行
循环,但是,现在是2017年

这假设您保证在JSON对象中有与名称
“rates”
关联的内容,该内容将作为
列表进行解析

定义自定义反序列化器以成对使用名称值标记

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;
    }
}
这是我的解决方案

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()));
        }
ObjectMapper mapper=new ObjectMapper();
CurrencyServiceResponse CurrencySresp=
readValue(jsonStr,newtypereference(){});
currencyResp.setRates(新ArrayList());
对于(Map.Entry:currencyResp.getRateMap().entrySet()){
currencyResp.getRates().add(
新的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
    }
}
公共类CurrencyServiceResponse{
@JsonProperty(“基础”)
私有字符串基;
@JsonProperty(“日期”)
私人日期;
@JsonProperty(“费率”)
私有地图;
@杰索尼奥雷
私人名单费率;
//接球手和接球手
公共静态课率{
私有字符串名称;
私人双重价值;
公共费率(字符串名称,双精度值){
this.name=名称;
这个值=值;
}
//接球手和接球手
}
}

您的意思是数组类似于对象之外?您可能会使用这样的方法:因为您试图在java端将json映射转换为普通数量的属性。谢谢sombriks,我将尝试我更新的问题,我需要与jackson一起创建convertedJsonObjectArrayList。我知道,我想知道是否有一种自动化的方法,可能是一个没有if case的for循环,我认为不是,因为在反序列化类中需要一个注释,该注释将获取源json对象并将其转换为新类(Currency)的数组。我没有读过。但就我所知,除非其他人能指出这种注释,否则你会被我写的东西或其他选项所困扰。选择对您有帮助的内容这与他们想要的阵列/列表有什么关系?他们不是问如何获得双打的价格。我问了杰克逊,但再次感谢,斯特罗里奥斯是对的