Gson игнорирует @JsonAdapter на полях JsonElement? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть объект для сериализации с использованием Gson:

class User {
    String firstname;
    String lastname;
    JsonElement opaqueData;
}

На верхнем уровне объекта я хочу, чтобы Gson игнорировал null поля (скажем, если lastname равно null, он не должен быть сериализован).

Но в поле opaqueData я хочу, чтобы null s был сериализован, поскольку предполагается, что он является блоком непрозрачных данных.Таким образом, использование new GsonBuilder().serializeNulls().create().toJson(user) не будет работать.

Но @JsonAdapter также не работает

class User {
    String firstname;
    String lastname;
    @JsonAdapter(NullAdapter.class)
    JsonElement opaqueData;
}

class NullAdapter extends TypeAdapter<JsonElement> {

    @Override
    public void write(JsonWriter out, JsonElement value) throws IOException {
        out.jsonValue(new GsonBuilder().serializeNulls().create().toJson(value));
    }

    @Override
    public JsonElement read(JsonReader in) throws IOException {
        // TODO Auto-generated method stub
        return null;
    }

}

Похоже, что Gson игнорирует адаптер.

Это ожидаемое поведение?Как это сделать без создания адаптера для всего класса User, а затем вручную сериализовать каждое поле?

1 Ответ

0 голосов
/ 24 сентября 2018

Gson не пытается адаптировать свой внутренний тип данных JsonElement.Я не знаю, есть ли смысл, поскольку JsonElement вид является адаптированным результатом.

Взглянув на исходный код Gson , вы можете увидеть там два метода верхнего уровня:

Для любого объекта

public String toJson(Object src) {
    if (src == null) {
        return toJson(JsonNull.INSTANCE);
    }
    return toJson(src, src.getClass());
}

Я думаю, что без копирования остальной части кода очевидно, что вышеупомянутый метод имеет поиск и настройку адаптеров (и запрос адаптера)заводы) в его пути исполнения.Но есть и такой метод, как:

Для JsonElement

public String toJson(JsonElement jsonElement) {
    StringWriter writer = new StringWriter();
    toJson(jsonElement, writer);
    return writer.toString();
}

, и для этого пути выполнения нет поиска и установки каких-либо адаптеров, так как JsonElement нетпредназначен для адаптации.

Так что, когда Gson ударит по любому JsonElement, он просто сериализует ti как отформатированную строку, и вы не можете повлиять на это с помощью любого адаптера.

Если вам действительно нужноСериализовать что-то подобное, может быть, вы могли бы создать класс-оболочку для JsonElement, что-то вроде:

public class JsonElementWrapper {
    public JsonElement jsonElement;
}

и настроить ваш TypeAdapter, чтобы адаптировать его к `null`` или фактическому значению.

...