programing

필드당 여러 GSON @SerializedName?

copysource 2022. 9. 15. 23:47
반응형

필드당 여러 GSON @SerializedName?

Gson에서 여러 JSON 필드를 단일 Java 객체 멤버 변수에 매핑할 수 있는 방법이 있습니까?

자바 수업이 있다고 칩시다.

public class MyClass {
    String id;
    String name;
}

이 싱글 클래스를 두 가지 다른 서비스로 이용하고 싶습니다.단, 이들 2개의 서비스는 데이터를 반환하는 방법이 다릅니다.

{ "id": 2341, "person": "Bob" }

...그리고...

{ "id": 5382, "user": "Mary" }

...각각 다음과 같다.

이 두 가지를 모두 매핑할 수 있는 방법이 있을까요?"person"그리고."user"JSON 문자열의 필드nameJava 객체의 필드입니다.

(주의: JSON 문자열에서 Java 개체로 변환하기만 하면 됩니다.)

2015년 10월, Gson 버전 2.4(changelog)에서는 다음 항목에 대해 대체/복수 이름을 사용할 수 있는 기능이 추가되었습니다.@SerializedName디시리얼라이즈 할 때.커스텀 타입 어댑터는 불필요합니다.

사용방법:

자바

@SerializedName(value="name", alternate={"person", "user"})

코틀린

@SerializedName(value="name", alternate= ["person", "user"])

https://www.javadoc.io/doc/com.google.code.gson/gson/2.6.2/com/google/gson/annotations/SerializedName.html

코틀린 팬을 위해서

@SerializedName(value="name", alternate= ["person", "user"])

여러 개를 정의하는 것은 지원되지 않습니다.@SerializedNameGson의 필드에 주석을 추가합니다.

이유: 디폴트로는 Diserialization은 LinkedHashMap을 사용하여 관리되며 키는 착신 json의 필드명(커스텀클래스의 필드명 또는 serialized Names가 아님)으로 정의되며 1:1 매핑이 있습니다.실장(디시리얼라이제이션의 동작 방식)은, 다음의 Web 사이트에서 확인할 수 있습니다.ReflectiveTypeAdapterFactory학급의 내부 계급Adapter<T>read(JsonReader in)방법.

솔루션:다음을 처리하는 사용자 지정 TypeAdapter를 작성할 수 있습니다.name,person그리고.userjson은 태그를 지정하여 사용자 지정 클래스의 이름 필드에 매핑합니다.MyClass:

class MyClassTypeAdapter extends TypeAdapter<MyClass> {

    @Override
    public MyClass read(final JsonReader in) throws IOException {
        final MyClass myClassInstance = new MyClass();

        in.beginObject();
        while (in.hasNext()) {
            String jsonTag = in.nextName();
            if ("id".equals(jsonTag)) {
                myClassInstance.id = in.nextInt();
            } else if ("name".equals(jsonTag) 
                    || "person".equals(jsonTag)
                    || "user".equals(jsonTag)) {
                myClassInstance.name = in.nextString();
            }
        }
        in.endObject();

        return myClassInstance;
    }

    @Override
    public void write(final JsonWriter out, final MyClass myClassInstance)
            throws IOException {
        out.beginObject();
        out.name("id").value(myClassInstance.id);
        out.name("name").value(myClassInstance.name);
        out.endObject();
    }
}

테스트 케이스:

    String jsonVal0 = "{\"id\": 5382, \"user\": \"Mary\" }";
    String jsonVal1 = "{\"id\": 2341, \"person\": \"Bob\"}";

    final GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassTypeAdapter());
    final Gson gson = gsonBuilder.create();

    MyClass myClassInstance0 = gson.fromJson(jsonVal0, MyClass.class);
    MyClass myClassInstance1 = gson.fromJson(jsonVal1, MyClass.class);

    System.out.println("jsonVal0 :" + gson.toJson(myClassInstance0));
    // output: jsonVal0 :{"id":5382,"name":"Mary"}

    System.out.println("jsonVal1 :" + gson.toJson(myClassInstance1));
    // output: jsonVal1 :{"id":2341,"name":"Bob"}

TypeAdapters의 예.

2016.04.06 편집 : @Mathieu Castets 님의 답변에 따라 작성하였으므로, 현재 지원되고 있습니다.(이 문제는 정답입니다.)

public abstract String [ ]대체
반환: 필드 역직렬화 시 대체 필드 이름
기본값: {}

KOTLIN의 경우 아래를 사용했지만 작동하지 않습니다.

@SerializedName(value="name", alternate= ["person", "user"])

그래서 편집했는데 잘 되네!!

@SerializedName(value="name", alternate= arrayOf("person", "user"))

언급URL : https://stackoverflow.com/questions/25707728/multiple-gson-serializedname-per-field

반응형