programing

개체의 한 변수에 대한 Gson 사용자 지정 디세럴라이저

mbctv 2023. 4. 1. 09:53
반응형

개체의 한 변수에 대한 Gson 사용자 지정 디세럴라이저

문제의 예:

Apple 오브젝트 타입이 있습니다.Apple에는 다음과 같은 멤버 변수가 있습니다.

String appleName; // The apples name
String appleBrand; // The apples brand
List<Seed> seeds; // A list of seeds the apple has

그리고 시드 오브젝트는 다음과 같습니다.

String seedName; // The seeds name
long seedSize; // The size of the seed

이제 내가 사과 물체를 얻었을 때, 사과는 씨앗이 하나 이상 있을 수도 있고 씨앗이 하나 있을 수도 있고 없을 수도 있어요!

시드가 1개인 JSON 애플 예시:

{
"apple" : {
   "apple_name" : "Jimmy", 
   "apple_brand" : "Awesome Brand" , 
   "seeds" : {"seed_name":"Loopy" , "seed_size":"14" }
  }
}

2개의 시드를 가진 JSON 애플 예시:

{
"apple" : {
   "apple_name" : "Jimmy" , 
   "apple_brand" : "Awesome Brand" , 
   "seeds" : [ 
      { 
         "seed_name" : "Loopy",
         "seed_size" : "14"
      },
      {
         "seed_name" : "Quake",
         "seed_size" : "26"
      } 
  ]}
}

첫 번째 예는 시드의 JSONObject이고 두 번째 예는 시드의 JSONAray입니다.현재 JSON의 일관성이 없고 가장 쉬운 방법은 JSON 자체를 수정하는 것입니다만, 유감스럽게도 JSON을 다른 사람에게서 받고 있기 때문에 수정할 수 없습니다.이 문제를 해결하는 가장 쉬운 방법은 무엇입니까?

의 커스텀 타입 어댑터를 등록해야 합니다.Appletype 어댑터에서 어레이가 지정되었는지 단일 개체가 지정되었는지 확인하는 논리를 추가합니다.이 정보를 사용하여 다음 정보를 생성할 수 있습니다.Apple물건.

아래 코드에 따라 Apple 모델 개체를 수정하여seeds필드는 자동으로 해석되지 않습니다.변수 선언을 다음과 같이 변경합니다.

private List<Seed> seeds_funkyName;

코드는 다음과 같습니다.

GsonBuilder b = new GsonBuilder();
b.registerTypeAdapter(Apple.class, new JsonDeserializer<Apple>() {
    @Override
    public Apple deserialize(JsonElement arg0, Type arg1,
        JsonDeserializationContext arg2) throws JsonParseException {
        JsonObject appleObj = arg0.getAsJsonObject();
        Gson g = new Gson();
        // Construct an apple (this shouldn't try to parse the seeds stuff
        Apple a = g.fromJson(arg0, Apple.class);
        List<Seed> seeds = null;
        // Check to see if we were given a list or a single seed
        if (appleObj.get("seeds").isJsonArray()) {
            // if it's a list, just parse that from the JSON
            seeds = g.fromJson(appleObj.get("seeds"),
                    new TypeToken<List<Seed>>() {
                    }.getType());
        } else {
            // otherwise, parse the single seed,
            // and add it to the list
            Seed single = g.fromJson(appleObj.get("seeds"), Seed.class);
            seeds = new ArrayList<Seed>();
            seeds.add(single);
        }
        // set the correct seed list
        a.setSeeds(seeds);
        return a;
    }
});

상세한 것에 대하여는, Gson 가이드를 참조해 주세요.

저도 같은 문제에 직면했어요.나의 솔루션은 조금 더 심플하고 일반적이라고 생각한다.

Gson gson = new GsonBuilder()
        .registerTypeAdapter(List.class, new JsonSerializer<List<?>>() {
            @Override
            public JsonElement serialize(List<?> list, Type t,
                    JsonSerializationContext jsc) {
                if (list.size() == 1) {
                    // Don't put single element lists in a json array
                    return new Gson().toJsonTree(list.get(0));
                } else {
                    return new Gson().toJsonTree(list);
                }
            }
        }).create();

물론 오리지널 포스터에 동의합니다만, 가장 좋은 해결책은 json을 바꾸는 것입니다.사이즈 1의 어레이에는 문제가 없으며, 시리얼화와 시리얼 해제는 더욱 심플해집니다.안타깝게도 이러한 변경은 사용자의 통제를 벗어나는 경우가 있습니다.

GSON에서는 Lists 대신 어레이를 사용하고 있으며, 이러한 문제는 없습니다.http://app.ecwid.com/api/v1/1003/product?id=4064을 참조해 주십시오.이 "categories" 속성은 실제로는 하나의 요소를 가진 Javascript 배열입니다.다음과 같이 선언되었습니다.

카테고리[] 카테고리

UPDATE: TypeToken 및 커스텀시리얼라이제이션의 사용이 도움이 될 수 있습니다.https://sites.google.com/site/gson/gson-user-guide 를 참조해 주세요.

JSON을 변경할 수 없는 경우(다른 사람에게서 받은 것처럼) 가장 간단한 해결책은 Java 클래스에서 Apple 및 Seed 클래스 변수 이름을 구문 분석된 JSON과 일치하도록 변경하는 것입니다.

다음과 같이 변경합니다.

Apple Class
-----------
String apple_name; // The apples name
String apple_brand; // The apples brand
List<Seed> seeds; // A list of seeds the apple has
And the seed object looks as follows.

Seed Class
-----------
String seed_name; // The seeds name
long seed_size; // The size of the seed

언급URL : https://stackoverflow.com/questions/6014674/gson-custom-deseralizer-for-one-variable-in-an-object

반응형