Gson , factory , Gson () . , , AccountState ReflectiveTypeAdapterFactory ReflectiveTypeAdapterFactory.Adapter, , GsonBuilder.
final class AccountState {
@JsonAdapter(PackedBooleanTypeAdapterFactory.class)
final Boolean rated = null;
}
, PackageBooleanTypeAdapterFactory :
final class PackedBooleanTypeAdapterFactory
implements TypeAdapterFactory {
private PackedBooleanTypeAdapterFactory() {
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
if ( typeToken.getRawType() == Boolean.class ) {
final TypeAdapter<Boolean> typeAdapter = new PackedIntegerTypeAdapter(gson);
@SuppressWarnings("unchecked")
final TypeAdapter<T> castTypeAdapter = (TypeAdapter<T>) typeAdapter;
return castTypeAdapter;
}
return null;
}
private static final class PackedIntegerTypeAdapter
extends TypeAdapter<Boolean> {
private final Gson gson;
private PackedIntegerTypeAdapter(final Gson gson) {
this.gson = gson;
}
@Override
public void write(final JsonWriter out, final Boolean value) {
throw new UnsupportedOperationException();
}
@Override
public Boolean read(final JsonReader in)
throws MalformedJsonException {
final JsonElement jsonElement = gson.fromJson(in, JsonElement.class);
if ( jsonElement.isJsonNull() ) {
return null;
}
if ( jsonElement.isJsonPrimitive() ) {
return jsonElement
.getAsJsonPrimitive()
.getAsBoolean();
}
if ( jsonElement.isJsonObject() ) {
return jsonElement
.getAsJsonObject()
.getAsJsonPrimitive("value")
.getAsBoolean();
}
throw new MalformedJsonException("Cannot parse: " + jsonElement);
}
}
}
:
public static void main(final String... args) {
parseAndDump("{\"rated\":null}");
parseAndDump("{\"rated\":true}");
parseAndDump("{\"rated\":{\"value\":true}}");
}
private static void parseAndDump(final String json) {
final AccountState accountState = gson.fromJson(json, AccountState.class);
System.out.println(accountState.rated);
}
:
true
, JsonSerializer JsonDeserializer - ( JSON , ). . : . : .
final class AccountState {
@JsonAdapter(PackedBooleanTypeAdapter.class)
final Boolean rated = null;
}
, rated , Gson JSON (JsonElement s).
final class PackedBooleanTypeAdapter
extends TypeAdapter<Boolean> {
private PackedBooleanTypeAdapter() {
}
@Override
public void write(final JsonWriter out, final Boolean value) {
throw new UnsupportedOperationException();
}
@Override
public Boolean read(final JsonReader in)
throws IOException {
final JsonToken token = in.peek();
switch ( token ) {
case NULL:
return parseAsNull(in);
case BOOLEAN:
return parseAsBoolean(in);
case BEGIN_OBJECT:
return parseAsObject(in);
case BEGIN_ARRAY:
case END_ARRAY:
case END_OBJECT:
case NAME:
case STRING:
case NUMBER:
case END_DOCUMENT:
throw new MalformedJsonException("Cannot parse: " + token);
default:
throw new AssertionError(token);
}
}
private Boolean parseAsNull(final JsonReader in)
throws IOException {
in.nextNull();
return null;
}
private Boolean parseAsBoolean(final JsonReader in)
throws IOException {
return in.nextBoolean();
}
private Boolean parseAsObject(final JsonReader in)
throws IOException {
in.beginObject();
final String property = in.nextName();
if ( !property.equals("value") ) {
throw new MalformedJsonException("Unexpected property: " + property);
}
final boolean value = in.nextBoolean();
in.endObject();
return value;
}
}
. . , Gson GsonBuilder. , Retrofit 2, GsonConverterFactory - ( , Gson Retrofit 2?).