Gson: How do I parse polymorphic values that can be either lists or strings?

前端 未结 4 417
心在旅途
心在旅途 2021-01-27 11:57

I need to parse a JSON file that contains long list of customers. In the JSON file each customer may have one id as a string:

{
  \"cust_id\": \"87655\",
  ...
}         


        
相关标签:
4条回答
  • 2021-01-27 12:19

    Refer this.

    Now the problem is that you will have to write your own code on the returned map to get the desired result.

    0 讨论(0)
  • 2021-01-27 12:20

    Try method overriding:

    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;
        }
    }
    

    Now In the code all values of CUSTID will be arrays instead of strings

    0 讨论(0)
  • 2021-01-27 12:22

    You can just simply specify all values as array, even if is just one value.

    {
      "cust_id": ["87655"],
      ...
    },
    

    UPDATE: If you cannot change the json, you can bind every field in Customer class except custId and set it manually.

    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;
        }
    }
    

    And then parse manually:

    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)));
    }
    
    0 讨论(0)
  • 2021-01-27 12:43

    If you want to handle both scenarios you can use a custom deserializer. Of course, you have to change the "cust_id" variable to be a list or an array.

    Main:

    String json1 = "{\"cust_id\": \"87655\"}";
    String json2 = "{\"cust_id\": [\"12345\", \"45678\"]}";
    
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Customer.class, new CustomerDeserializer());
    Gson gson = gsonBuilder.create();
    
    Customer customer1 = gson.fromJson(json1, Customer.class);
    System.out.println(customer1);
    
    Customer customer2 = gson.fromJson(json2, Customer.class);
    System.out.println(customer2);
    

    Customer

    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;
        }
    }
    

    CustomerDeserializer

    public class CustomerDeserializer implements JsonDeserializer<Customer> {
    
    @Override
    public Customer deserialize(JsonElement jsonElement, Type typeOf, JsonDeserializationContext context) throws JsonParseException {
        Customer result = null;
        Gson gson = new Gson();
    
        try {
            // try to deserialize by assuming JSON has a list
            result = gson.fromJson(jsonElement, Customer.class);
        } catch (JsonSyntaxException jse) {
            // error here means JSON has a single string instead of a list
    
            try {
                // get the single ID
                String custId = jsonElement.getAsJsonObject().get("cust_id").getAsString();
    
                result = new Customer();
                result.setCustId(Arrays.asList(new String[] {custId}));
            } catch (Exception e) {
                // more error handling here
                e.printStackTrace();
            }
        }
    
        return result;
    }
    

    }

    Output

    Customer [custId=[87655]]
    Customer [custId=[12345, 45678]]
    
    0 讨论(0)
提交回复
热议问题