Поскольку вы все еще должны отмечать поле, которое должно обрабатываться по-разному, Gson не предоставляет ничего подобного. Однако вы можете реализовать такое поведение. Ближе всего к вашему запросу @JsonAdapter
Предположим, у вас есть
private static final String JSON = "{\n"
+ " \"user\": {\n"
+ " \"some_ids\": {\n"
+ " \"useless_key\": [\n"
+ " \"22a074ff-91bf-4599-9a9e-374d3f01b6e0\",\n"
+ " \"66c8ce85-f162-4d92-a836-198a17764efa\",\n"
+ " \"d0519a9e-bfa2-446c-bb98-746136a3e513\"\n"
+ " ]\n"
+ " }\n"
+ " }\n"
+ "}";
public static void main(final String... args) {
final Gson gson = new Gson();
final Response response = gson.fromJson(JSON, Response.class);
out.println(response.getUser().getSomeIds());
}
определяется DTO Response
класс, как следует:
final class Response {
private Response() { }
@SerializedName("user")
private final User user = null;
User getUser() { return user; }
static final class User {
private User() { }
@SerializedName("some_ids")
@JsonAdapter(IdsTypeAdapter.class)
private final List<String> someIds = null;
List<String> getSomeIds() { return someIds; }
}
}
тип адаптера, указанный в @JsonAdapter(IdsTypeAdapter.class)
выше может быть реализован в виде следует:
final class IdsTypeAdapter
extends TypeAdapter<List<String>> {
private static final String USELESS_PROPERTY = "useless_key";
private IdsTypeAdapter() {
}
@Override
public void write(final JsonWriter writer, final List<String> value) {
throw new UnsupportedOperationException();
}
@Override
public List<String> read(final JsonReader reader)
throws IOException {
reader.beginObject();
if (!reader.nextName().equals(USELESS_PROPERTY)) {
throw new UnsupportedOperationException("Expected: " + USELESS_PROPERTY);
}
reader.beginArray();
final List<String> ids = new ArrayList<>();
while (reader.peek() == STRING) {
ids.add(reader.nextString());
}
reader.endArray();
reader.endObject();
return unmodifiableList(ids);
}
}
Адаптер типа выше довольно прост и способствует чтению потока, чтобы повысить производительность (адаптеры типа также требуются аннотацией @JsonAdapter
). И результат:
[22a074ff-91bf-4599-9a9e-374d3f01b6e0, 66c8ce85-f162-4d92-a836-198a17764efa, d0519a9e-bfa2-446c-bb98-746136a3e513]
Другой вариант использование десериализаторов JSON (может быть зарегистрировано в GsonBuilder
), но последние оказывают влияние на производительность, поскольку они требуют, чтобы все дерево JSON было создано до начала процесса десериализации. Еще одна проблема с десериализаторами JSON заключается в том, что Gson не поддерживает пользовательские аннотации, поэтому для того, чтобы отмечать «специальные» поля, вам все равно нужно создать класс-оболочку, такой как class StringIds extends ArrayList<String>
, который позже даже потребовал бы контекста десериализации для десериализации заданного JsonElement
до List<String>
, а затем перенаправлено обратно на StringIds
. Это дорого. Я бы пошел с адаптерами типа.
Не будет ли это просто пропустить все данные внутри ключа, и я думаю, что вопрос здесь должен также иметь эти данные? –