Java Gson:如何解析可以是列表或字符串的多态值?

Java Gson:如何解析可以是列表或字符串的多态值?,java,json,gson,Java,Json,Gson,我需要解析一个包含一长串客户的JSON文件。在JSON文件中,每个客户可以有一个id作为字符串: { "cust_id": "87655", ... }, 或几个ID作为一个数组: { "cust_id": [ "12345", "45678" ], ... }, 客户类别如下: 公共类客户{ @序列化名称(“客户id”) @暴露 私有字符串custId; 公共字符串getCustId(){ 返回客户I

我需要解析一个包含一长串客户的JSON文件。在JSON文件中,每个客户可以有一个id作为字符串:

{
  "cust_id": "87655",
  ...
},
或几个ID作为一个数组:

   {
      "cust_id": [
        "12345",
        "45678"
      ],
      ...
    },
客户
类别如下:

公共类客户{
@序列化名称(“客户id”)
@暴露
私有字符串custId;
公共字符串getCustId(){
返回客户ID;
}
公共void setCustId(字符串custId){
this.custId=custId;
}
}
我使用Gson解析JSON:

Gson gson = new Gson()
Customers customers1 = gson.fromJson(json, Customers.class)
并且它在尝试解析数组时失败,因为
com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:需要一个字符串,但在BEGIN_ARRAY
中失败

失败的原因很清楚


我的问题:处理这两种情况的最佳方法是什么(当id是字符串和字符串数组时),如果我不能更改json文件结构

您只需将所有值指定为数组,即使只有一个值

{
  "cust_id": ["87655"],
  ...
},
更新:如果无法更改json,则可以绑定
Customer
类中除
custId
之外的所有字段并手动设置

public class Customer {
    private String[] custId;

    public String getCustId() {
        return custId;
    }

    public void setCustId(String custId) {
        custId = new String[] {custId};
    }

    public void setCustId(String[] custId) {
        this.custId = custId;
    }
}
然后手动解析:

Gson gson = new Gson();
Customers customers = gson.fromJson(json, Customers.class);
Object custId = new JSONObject(json).get("cust_id");
if (custId instanceof String) {
  customers.setCustId((String) custId);
else if (custId instanceof JSONArray) {
  customers.setCustId(convertToStringArray(new JSONArray(custId)));
}

您只需将所有值指定为数组,即使只有一个值

{
  "cust_id": ["87655"],
  ...
},
更新:如果无法更改json,则可以绑定
Customer
类中除
custId
之外的所有字段并手动设置

public class Customer {
    private String[] custId;

    public String getCustId() {
        return custId;
    }

    public void setCustId(String custId) {
        custId = new String[] {custId};
    }

    public void setCustId(String[] custId) {
        this.custId = custId;
    }
}
然后手动解析:

Gson gson = new Gson();
Customers customers = gson.fromJson(json, Customers.class);
Object custId = new JSONObject(json).get("cust_id");
if (custId instanceof String) {
  customers.setCustId((String) custId);
else if (custId instanceof JSONArray) {
  customers.setCustId(convertToStringArray(new JSONArray(custId)));
}

尝试方法重写:

public class Customer {

    @SerializedName("cust_id")
    @Expose
    private String custId;

    public void setCustId(String custId) {
        this.custId = {custId};
    }

    public String[] getCustId() {
        return custId;
    }

    @override
    public void setCustId(String[] custId) {
        this.custId = custId;
    }
}

现在,在代码中,
CUSTID
的所有值都将是数组而不是字符串

尝试
方法重写

public class Customer {

    @SerializedName("cust_id")
    @Expose
    private String custId;

    public void setCustId(String custId) {
        this.custId = {custId};
    }

    public String[] getCustId() {
        return custId;
    }

    @override
    public void setCustId(String[] custId) {
        this.custId = custId;
    }
}

现在,在代码中,
CUSTID
的所有值都将是数组而不是字符串

如果要处理这两种情况,可以使用自定义反序列化器。当然,您必须将“cust_id”变量更改为列表或数组

主要内容:

顾客

public class Customer {

    @SerializedName("cust_id")
    private List<String> custId;

    public List<String> getCustId() {
        return custId;
    }

    public void setCustId(List<String> custId) {
        this.custId = custId;
    }
}

如果要处理这两种情况,可以使用自定义反序列化器。当然,您必须将“cust_id”变量更改为列表或数组

主要内容:

顾客

public class Customer {

    @SerializedName("cust_id")
    private List<String> custId;

    public List<String> getCustId() {
        return custId;
    }

    public void setCustId(List<String> custId) {
        this.custId = custId;
    }
}
参考

现在的问题是,您必须在返回的映射上编写自己的代码以获得所需的结果。

请参阅


现在的问题是,您必须在返回的映射上编写自己的代码以获得所需的结果。

我无法更改json。它是提供给我的。我不能更改json。这是提供给我的。请注意,您的问题针对的主题在S.O.非常琐碎。要求以最有效的方式将单个和多个案例“对齐”到列表中,但公认的答案以非常简单的方式做到了这一点:需要构造函数,需要“级联异常展开”,忽略特定的
Gson
实例配置等。可能重复的请注意,您的问题针对的主题在S.O.非常琐碎。要求以最有效的方式将单个和多个案例“对齐”到列表中,但公认的答案以非常简单的方式进行:需要构造函数,需要“级联异常展开”,忽略特定的
Gson
实例配置等。