source

Gson - 동일한 필드 이름, 다른 유형

nicesource 2023. 3. 20. 23:19
반응형

Gson - 동일한 필드 이름, 다른 유형

저는 오늘 다른 질문으로 이것을 물었지만 표현 방식 때문에 어떤 해결책도 얻을 수 없을 것 같습니다.

다음과 같은 데이터를 가진 json 입력이 있습니다.

제이슨

보시는 와 같이 option_value 항목은 한 개체에서는 배열이고 다른 개체에서는 단순한 문자열입니다.

어떻게 하면 Gson에게 이 문제를 제대로 처리하게 할 수 있을까요?클래스에서는 이것을 List 객체로 기술하고 있기 때문에 option_value가 배열인 처음 몇 개의 항목에서는 동작하지만 문자열이 되면 앱이 크래쉬하고 json 해석 예외가 발생합니다.

이에 대한 해결 방법이 있습니까?

갱신하다

요청에 따라 내 수업의 관련 부분을 추가합니다.

public class Options
    {
        String product_option_id;
        String option_id;
        String name;
        String type;
        String required;
        List<OptionValue> option_value;

        // get set stuff here

        public class OptionValue
        {
            String product_option_value_id;
            String option_value_id;
            String name;
            String image;
            String price;
            String price_prefix;

            // get set stuff here
        }
    }

솔루션을 준비했습니다:) 이를 위해서는 커스텀디시리얼라이저를 사용해야 합니다.수업을 다음과 같이 재작성합니다.

    public class Options{

        @SerializedName ("product_option_id");
        String mProductOptionId;

        @SerializedName ("option_id");
        String mOptionId;

        @SerializedName ("name");
        String mName;

        @SerializedName ("type");
        String mType;

        @SerializedName ("required");
        String mRequired;

        //don't assign any serialized name, this field will be parsed manually
        List<OptionValue> mOptionValue;

        //setter
        public void setOptionValues(List<OptionValue> optionValues){
             mOptionValue = optionValues;
        }

        // get set stuff here
        public class OptionValue
        {
            String product_option_value_id;
            String option_value_id;
            String name;
            String image;
            String price;
            String price_prefix;

            // get set stuff here
        }

    public static class OptionsDeserializer implements JsonDeserializer<Options> {

        @Override
        public Offer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            Options options = new Gson().fromJson(json, Options.class);
            JsonObject jsonObject = json.getAsJsonObject();

            if (jsonObject.has("option_value")) {
                JsonElement elem = jsonObject.get("option_value");
                if (elem != null && !elem.isJsonNull()) {  
                     String valuesString = elem.getAsString();
                     if (!TextUtils.isEmpty(valuesString)){
                         List<OptionValue> values = new Gson().fromJson(valuesString, new TypeToken<ArrayList<OptionValue>>() {}.getType());
                         options.setOptionValues(values);
                     }
                }
            }
            return options ;
        }
    }
    }

Gson이 json을 해석할 수 있도록 하기 전에 커스텀 디시리얼라이저를 등록해야 합니다.

    Gson gson = new GsonBuilder()              
                .registerTypeAdapter(Options.class, new Options.OptionsDeserilizer())               
                .create();

이제 - 전화만 하면 됩니다.

    Options options = gson.fromJson(json, Options.class);

내 상황에서는 이름이 같은 필드가 "data"입니다.{} 또는 "data":[array_with_real_data]따라서 승인된 답변의 코드는 다음과 같이 약간 수정해야 합니다.

@Override
public MyClass deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
    MyClass bean = new Gson().fromJson(json, MyClass.class);
    JsonObject jsonObject = json.getAsJsonObject();

    if (jsonObject.has("data")) {
        JsonArray array = jsonObject.getAsJsonArray("data");
        if (array != null && !array.isJsonNull()) {
            List<Data> data = new Gson().fromJson(array, new TypeToken<ArrayList<Data>>() {}.getType());
            bean.realData = data;
        }
    }
    return bean ;
}

도움이 됐으면 좋겠네요

언급URL : https://stackoverflow.com/questions/28319473/gson-same-field-name-different-types

반응형