bestsource

Gson 시리얼라이제이션에서 필드 시퀀스를 유지하는 방법

bestsource 2023. 2. 17. 21:29
반응형

Gson 시리얼라이제이션에서 필드 시퀀스를 유지하는 방법

그런 것 같다Gson.toJson(Object object)는 오브젝트의 랜덤하게 전개된 필드를 사용하여 JSON 코드를 생성합니다.필드 순서를 어떻게 고칠 수 있는 방법이 있습니까?

public class Foo {
    public String bar;
    public String baz;
    public Foo( String bar, String baz ) {
        this.bar = bar;
        this.baz = baz;
    }
}
Gson gson = new Gson();
String jsonRequest = gson.toJson(new Foo("bar","baz"));

jsonRequest 문자열은 다음과 같습니다.

  • { "bar":"bar", "baz":"baz" }(정답)
  • { "baz":"baz", "bar":"bar" }(시퀀스)

커스텀 JSON 시리얼라이저를 작성해야 합니다.

예.

public class FooJsonSerializer implements JsonSerializer<Foo> {

    @Override
    public JsonElement serialize(Foo foo, Type type, JsonSerializationContext context) {
        JsonObject object = new JsonObject();
        object.add("bar", context.serialize(foo.getBar());
        object.add("baz", context.serialize(foo.getBaz());
        // ...
        return object;
    }

}

다음과 같이 사용합니다.

Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class, new FooJsonSerializer()).create();
String json = gson.toJson(foo);
// ...

그러면 시리얼라이저에서 지정한 순서가 유지됩니다.

다음 항목도 참조하십시오.

GSON이 필드 순서의 정의를 지원하지 않는 경우 지원하는 다른 라이브러리가 있습니다.를 들어 잭슨은 이를 @JsonPropertyOrder로 정의할 수 있습니다.독자적인 커스텀 시리얼라이저를 지정해야 하는 것은 저에게 매우 힘든 일인 것 같습니다.

또한 JSON 사양에 따라 어플리케이션이 특정 필드 순서를 예상해서는 안 된다는 점에 동의합니다.

실제로 Gson.toJson(개체 객체)은 랜덤 순서로 필드를 생성하지 않습니다.결과 json의 순서는 필드 이름의 리터럴시퀀스에 따라 달라집니다.

저도 같은 문제가 있어서 수업 시간에 부동산 이름을 문자 그대로 나열해서 해결했어요.

질문의 예에서는 항상 다음 jsonRequest가 반환됩니다.

{ "bar":"bar", "baz":"baz" }

특정 순서를 지정하려면 필드 이름을 변경해야 합니다(예:baz차례가 제일 먼저다bar:

public class Foo {
    public String f1_baz;
    public String f2_bar;

    public Foo ( String f1_baz, String f2_bar ) {
        this.f1_baz = f1_baz;
        this.f2_bar = f2_bar;
    }
}

jsonRequest는{ "f1_baz ":"baz", "f2_bar":"bar" }

다음은 특정 디렉토리의 json 텍스트 파일을 루프하고 그 위에 정렬된 버전으로 쓰기 위한 솔루션입니다.

private void standardizeFormat(File dir) throws IOException {
    File[] directoryListing = dir.listFiles();
    if (directoryListing != null) {
        for (File child : directoryListing) {
            String path = child.getPath();
            JsonReader jsonReader = new JsonReader(new FileReader(path));

            Gson gson = new GsonBuilder().setPrettyPrinting().registerTypeAdapter(LinkedTreeMap.class, new SortedJsonSerializer()).create();
            Object data = gson.fromJson(jsonReader, Object.class);
            JsonWriter jsonWriter = new JsonWriter(new FileWriter(path));
            jsonWriter.setIndent("  ");
            gson.toJson(data, Object.class, jsonWriter);
            jsonWriter.close();
        }
    }
}

private class SortedJsonSerializer implements JsonSerializer<LinkedTreeMap> {
    @Override
    public JsonElement serialize(LinkedTreeMap foo, Type type, JsonSerializationContext context) {
        JsonObject object = new JsonObject();
        TreeSet sorted = Sets.newTreeSet(foo.keySet());
        for (Object key : sorted) {
            object.add((String) key, context.serialize(foo.get(key)));
        }
        return object;
    }
}

타입이 단순한 오브젝트일 때 Gson이 Linked Tree Map을 사용한다는 사실에 의존하기 때문에 매우 해킹적입니다.이것은 구현에 대한 자세한 내용은 보장되지 않을 수 있습니다.어쨌든, 내 단명 목적에는 충분해...

언급URL : https://stackoverflow.com/questions/6365851/how-to-keep-fields-sequence-in-gson-serialization

반응형