没有自定义序列化程序,是否可以对该字符串进行Jackson序列化?

时间:2019-05-13 20:10:03

标签: java json jackson

我想序列化作为POJO收到的JSON-String,以便在我的代码中进一步使用,但是我在不编写自定义序列化程序的情况下仍在努力工作。

我会更喜欢作为解决方案而无需编写自定义序列化程序,但是如果那是我唯一可能编写的方法。

此外,我认为我收到的数据是一个奇怪的JSON,因为我请求的列表不是使用[]作为列表发送,而是使用{}作为对象发送。 < / p>

我收到以下列表/对象(简称):

{
    "results": {
        "ALL": {
            "currencyName": "Albanian Lek",
            "currencySymbol": "Lek",
            "id": "ALL"
        },
        "XCD": {
            "currencyName": "East Caribbean Dollar",
            "currencySymbol": "$",
            "id": "XCD"
        },
        "EUR": {
            "currencyName": "Euro",
            "currencySymbol": "â?¬",
            "id": "EUR"
        },
        "BBD": {
            "currencyName": "Barbadian Dollar",
            "currencySymbol": "$",
            "id": "BBD"
        },
        "BTN": {
            "currencyName": "Bhutanese Ngultrum",
            "id": "BTN"
        },
        "BND": {
            "currencyName": "Brunei Dollar",
            "currencySymbol": "$",
            "id": "BND"
        }
    }
}

我为内部对象创建了第一个POJO,如下所示:

public class CurrencyDTO implements Serializable {

  private String currencyName;
  private String currencySymbol;
  private String currencyId;


  @JsonCreator
  public CurrencyDTO( @JsonProperty( "currencyName" ) String currencyName, @JsonProperty( "currencySymbol" ) String currencySymbol,
                      @JsonProperty( "id" ) String currencyId )
  {
    this.currencyId = currencyId;
    this.currencyName = currencyName;
    this.currencySymbol = currencySymbol;
  }
}

本身很好。现在,我写了另一个POJO作为上面一层的数据包装,如下所示:

public class CurrencyListDTO implements Serializable {

  private List<Map<String, CurrencyDTO>> results;

  public CurrencyListDTO()
  {
  }

}

添加注释@JsonAnySetter或使用@JsonCreator都无济于事,所以我再次删除了它们,现在我想知道哪个小技巧可以实现json的正确序列化。

以下是我的例外情况:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token
 at [Source: (String)"{"results":{"ALL":{"currencyName":"Albanian Lek","currencySymbol":"Lek","id":"ALL"},"XCD":{"currencyName":"East Caribbean Dollar","currencySymbol":"$","id":"XCD"},"EUR":{"currencyName":"Euro","currencySymbol":"â?¬","id":"EUR"},"BBD":{"currencyName":"Barbadian Dollar","currencySymbol":"$","id":"BBD"},"BTN":{"currencyName":"Bhutanese Ngultrum","id":"BTN"},"BND":{"currencyName":"Brunei Dollar","currencySymbol":"$","id":"BND"},"XAF":{"currencyName":"Central African CFA Franc","id":"XAF"},"CUP":{"cur"[truncated 10515 chars]; line: 1, column: 12] (through reference chain: com.nico.Banking.api.data.dto.CurrencyListDTO["results"])

2 个答案:

答案 0 :(得分:3)

您的CurrencyListDTO应该如下所示。 results属性是JSON Object,应直接映射到Map。您可以使用CollectionkeySet方法将其转换为values

class CurrencyListDTO implements Serializable {

    private Map<String, CurrencyDTO> results;

    public Map<String, CurrencyDTO> getResults() {
        return results;
    }

    public void setResults(Map<String, CurrencyDTO> results) {
        this.results = results;
    }

    @Override
    public String toString() {
        return "CurrencyListDTO{" +
                "results=" + results +
                '}';
    }
}

答案 1 :(得分:3)

您应将CurrencyListDTO更改为:

public class CurrencyListDTO {
    private Map<String, CurrencyDTO> results;
    // getters and setters
}

因为响应对象中的results字段是另一个以currencyId为键且没有数组的对象。

然后您可以像这样创建货币列表:

ObjectMapper mapper = new ObjectMapper();
CurrencyListDTO result = mapper.readValue(json, CurrencyListDTO.class);
List<CurrencyDTO> currencies = new ArrayList<>(result.getResults().values());