下面列出了怎么用com.google.gson.TypeAdapter的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void write(JsonWriter out, Collection<E> collection) throws IOException {
if (collection == null) {
out.nullValue();
return;
}
out.beginArray();
for (E element : collection) {
if (element != null && elementType != element.getClass()
&& (elementType instanceof TypeVariable<?> || elementType instanceof Class<?>)) {
@SuppressWarnings("unchecked")
TypeAdapter<E> runtimeTypeAdapter = (TypeAdapter<E>) gson.getAdapter(TypeToken.get(element.getClass()));
runtimeTypeAdapter.write(out, element);
} else {
elementTypeAdapter.write(out, element);
}
}
out.endArray();
}
@Override
protected void configure() {
Multibinder<TypeAdapterFactory> typeAdapterFactoryBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<TypeAdapterFactory>() {});
typeAdapterFactoryBinder.addBinding().to(AddressTypeAdapterFactory.class);
typeAdapterFactoryBinder.addBinding().to(GsonReferenceTypeAdapterFactory.class);
typeAdapterFactoryBinder.addBinding().to(MessageTypeAdapterFactory.class);
typeAdapterFactoryBinder.addBinding().to(MessageBodyTypeAdapterFactory.class);
Multibinder<TypeAdapter<?>> typeAdapterBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<TypeAdapter<?>>() {});
typeAdapterBinder.addBinding().to(ProtocolDeviceIdTypeAdapter.class);
typeAdapterBinder.addBinding().to(HubMessageTypeAdapter.class);
Multibinder<JsonSerializer<?>> serializerBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<JsonSerializer<?>>() {});
serializerBinder.addBinding().to(ClientMessageTypeAdapter.class);
serializerBinder.addBinding().to(ResultTypeAdapter.class);
Multibinder<JsonDeserializer<?>> deserializerBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<JsonDeserializer<?>>() {});
deserializerBinder.addBinding().to(ClientMessageTypeAdapter.class);
deserializerBinder.addBinding().to(ResultTypeAdapter.class);
}
@Override
@SuppressWarnings("unchecked")
public <A> TypeAdapter<A> create(Gson gson, TypeToken<A> typeToken) {
Type type = typeToken.getType();
boolean isXor = typeToken.getRawType() == Xor.class;
boolean isParameterized = type instanceof ParameterizedType;
boolean isSSHResult = ResultSSHResultTypeAdapterFactory.isResultSSHResult(type);
if (isXor && isParameterized && !isSSHResult) {
Type leftType = ((ParameterizedType) type).getActualTypeArguments()[0];
Type rightType = ((ParameterizedType) type).getActualTypeArguments()[1];
TypeAdapter<?> rightAdapter = gson.getAdapter(TypeToken.get(rightType));
if (leftType.equals(SaltError.class)) {
return (TypeAdapter<A>) errorAdapter(rightAdapter);
}
TypeAdapter<?> leftAdapter = gson.getAdapter(TypeToken.get(leftType));
return (TypeAdapter<A>) xorAdapter(leftAdapter, rightAdapter);
} else {
return null;
}
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (typeToken.getRawType() != Timestamp.class) {
return null;
}
final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class);
return new TypeAdapter<Timestamp>() {
public Timestamp read(JsonReader in) throws IOException {
Date date = (Date) dateTypeAdapter.read(in);
return date != null ? new Timestamp(date.getTime()) : null;
}
public void write(JsonWriter out, Timestamp value) throws IOException {
dateTypeAdapter.write(out, value);
}
};
}
@Override
@SuppressWarnings({ "unchecked" })
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (!Collection.class.isAssignableFrom(typeToken.getRawType()))
return null;
Type[] elementTypes = TypeUtils.getElementTypes(typeToken, Collection.class);
if (elementTypes.length != 1)
return null;
Type elementType = elementTypes[0];
TypeAdapter<?> elementTypeAdapter;
if (elementType == Object.class)
elementTypeAdapter = new JsonElementTypeAdapter(gson);
else
elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
Supplier<Collection<Object>> constructor = getConstructor((Class<Collection<Object>>) typeToken.getRawType());
return (TypeAdapter<T>) create(gson, elementType, elementTypeAdapter, constructor);
}
@SuppressWarnings("unchecked")
@Override public void write(JsonWriter out, Object value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());
if (typeAdapter instanceof IrisObjectTypeAdapter) {
out.beginObject();
out.endObject();
return;
}
typeAdapter.write(out, value);
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
TypeAdapter<T> typeAdapter = null;
try {
if (type.getRawType() == List.class)
typeAdapter = new ArrayAdapter(
(Class) ((ParameterizedType) type.getType())
.getActualTypeArguments()[0]);
} catch (Exception e) {
e.printStackTrace();
}
return typeAdapter;
}
/**
* Helper method to serialize Java objects as json strings
* @param name name of object used for logging
* @param object object to be serialized
* @return Json representation of the object
*/
public static String toJson(String name, Object object) {
final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC)
// Tells Gson how to serialize fields with type of Class.
.registerTypeHierarchyAdapter(Class.class, new TypeAdapter<Class>() {
@Override
public void write(JsonWriter out, Class value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.getName());
}
}
@Override
public Class read(JsonReader in) {
throw new SamzaException("Deserialization from json is not supported.");
}
}).create();
try {
return gson.toJson(object);
} catch (Exception e) {
throw new SamzaException(String.format("Failed to serialize %s to json", name), e);
}
}
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<? super T> rawType = type.getRawType();
// Only deserialize classes decorated with @AutoGson.
AutoGson annotation = rawType.getAnnotation(AutoGson.class);
if (annotation != null) {
return (TypeAdapter<T>) gson.getAdapter(annotation.autoValueClass()).nullSafe();
} else if (rawType.equals(SlicingProgressEntity.class)) {
return (TypeAdapter<T>) SlicingProgressEntity.typeAdapter(gson).nullSafe();
} else if (rawType.equals(SlicingProgress.class)) {
return (TypeAdapter<T>) SlicingProgress.typeAdapter(gson).nullSafe();
}
return null;
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (ID_TYPE_TOKEN.equals(type)) {
return (TypeAdapter<T>) WRAPPED_ID_ADAPTER;
}
if (TIME_INSTANT_TYPE_TOKEN.equals(type)) {
return (TypeAdapter<T>) WRAPPED_TIME_INSTANT_ADAPTER;
}
if (BINARY_TYPE_TOKEN.equals(type)) {
return (TypeAdapter<T>) WRAPPED_BINARY_ADAPTER;
}
if (PATTERN_TYPE_TOKEN.equals(type)) {
return (TypeAdapter<T>) PATTERN_ADAPTER;
}
if (DECIMAL128_TYPE_TOKEN.equals(type)) {
return (TypeAdapter<T>) DECIMAL128_ADAPTER;
}
return null;
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (!Date.class.isAssignableFrom(type.getRawType())) {
return null;
}
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
// date formatters not thread safe :'(
synchronized (simpleDateFormat) {
out.value(simpleDateFormat.format((Date) value));
}
}
@Override
public T read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("read() is not implemented");
}
};
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class clazz = type.getRawType();
if (clazz == Primitive.class) {
//noinspection unchecked
return (TypeAdapter<T>) PRIMITIVE_TYPE_ADAPTER;
} else if (clazz == ObjectValue.class) {
//noinspection unchecked
return (TypeAdapter<T>) OBJECT_TYPE_ADAPTER;
} else if (clazz == Array.class) {
//noinspection unchecked
return (TypeAdapter<T>) ARRAY_TYPE_ADAPTER;
} else if (clazz == Null.class) {
//noinspection unchecked
return (TypeAdapter<T>) NULL_TYPE_ADAPTER;
} else if (clazz == Layout.class) {
//noinspection unchecked
return (TypeAdapter<T>) LAYOUT_TYPE_ADAPTER;
} else if (clazz == Value.class) {
//noinspection unchecked
return (TypeAdapter<T>) VALUE_TYPE_ADAPTER;
}
return null;
}
private <S> S readValue(JsonObject jsonObject, TypeToken<S> defaultTypeToken) throws IOException {
try {
TypeToken<S> actualTypeToken;
if (jsonObject.isJsonNull()) {
return null;
} else if (jsonObject.has(OBJECT_TYPE)) {
String className = jsonObject.get(OBJECT_TYPE).getAsString();
Class<S> klazz = (Class<S>) Class.forName(className);
actualTypeToken = TypeToken.get(klazz);
} else if (defaultTypeToken != null) {
actualTypeToken = defaultTypeToken;
} else {
throw new IOException("Could not determine TypeToken.");
}
TypeAdapter<S> delegate = this.gson.getDelegateAdapter(this.factory, actualTypeToken);
S value = delegate.fromJsonTree(jsonObject.get(OBJECT_DATA));
return value;
} catch (ClassNotFoundException cnfe) {
throw new IOException(cnfe);
}
}
@Override
public String toJson() {
if (gson == null) {
gson = new GsonBuilder().serializeNulls().setPrettyPrinting().registerTypeAdapter(File.class, new TypeAdapter<File>() {
@Override
public void write(JsonWriter jsonWriter, File file) throws IOException {
String fileAbsolutePath = (file == null ? null : file.getAbsolutePath());
jsonWriter.value(fileAbsolutePath);
}
@Override
public File read(JsonReader jsonReader) {
throw new UnsupportedOperationException("There is no support for deserializing transformation result objects at the moment");
}
}).create();
}
return gson.toJson(this);
}
private String toJson() {
if (gson == null) {
gson = new GsonBuilder().serializeNulls().setPrettyPrinting().registerTypeAdapter(File.class, new TypeAdapter<File>() {
@Override
public void write(JsonWriter jsonWriter, File file) throws IOException {
String fileAbsolutePath = (file == null ? null : file.getAbsolutePath());
jsonWriter.value(fileAbsolutePath);
}
@Override
public File read(JsonReader jsonReader) {
throw new UnsupportedOperationException("There is no support for deserializing UpgradePathTransformationRequest objects at the moment");
}
}).create();
}
return gson.toJson(this);
}
/**
* Transforms the given enum constant to lower case. If a {@code SerializedName} annotation is
* present, the default adapter result is returned.
*
* @param enumConstant the enumeration constant
* @param delegateAdapter the default adapter of the given type
* @return the transformed string representation of the constant
*/
private <T> String transform(T enumConstant, TypeAdapter<T> delegateAdapter) {
try {
final String enumValue = ((Enum) enumConstant).name();
final boolean hasSerializedNameAnnotation =
enumConstant.getClass().getField(enumValue).isAnnotationPresent(SerializedName.class);
return hasSerializedNameAnnotation
? delegateAdapter.toJsonTree(enumConstant).getAsString()
: enumValue.toLowerCase();
} catch (NoSuchFieldException e) {
// should never happen
throw new RuntimeException(e);
}
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (!Optional.class.isAssignableFrom(type.getRawType())) {
return null;
}
final TypeAdapter delegateAdapter = gson.getAdapter(TypeToken.get(((ParameterizedType) type.getType()).getActualTypeArguments()[0]));
return new TypeAdapter<T>() {
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public void write(JsonWriter out, T value) throws IOException {
if (((Optional) value).isPresent()) {
delegateAdapter.write(out, ((Optional) value).get());
} else {
out.nullValue();
}
}
@Override
@SuppressWarnings("unchecked")
public T read(JsonReader in) throws IOException {
Object readObject = delegateAdapter.read(in);
if (readObject == null) {
return (T) Optional.empty();
} else {
return (T) Optional.of(readObject);
}
}
};
}
@Test
public void dateCodec() throws IOException {
TypeAdapter<Date> adapter = GsonCodecs.typeAdapterFromCodec(new DateCodec());
Date date = new Date();
BsonDocument doc = new BsonDocument();
BsonDocumentWriter writer = new BsonDocumentWriter(doc);
writer.writeStartDocument();
writer.writeName("$date");
adapter.write(new BsonWriter(writer), date);
writer.writeEndDocument();
check(doc.keySet()).hasSize(1);
check(doc.get("$date").getBsonType()).is(BsonType.DATE_TIME);
check(doc.get("$date").asDateTime().getValue()).is(date.getTime());
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (!Map.class.isAssignableFrom(typeToken.getRawType())) {
return null;
}
Type[] keyAndValueTypes = C$Gson$Types.getMapKeyAndValueTypes(type, C$Gson$Types.getRawType(type));
return new Adapter(gson, keyAndValueTypes[0], getKeyAdapter(gson, keyAndValueTypes[0]), keyAndValueTypes[1], gson.getAdapter(TypeToken.get(keyAndValueTypes[1])), this.constructorConstructor.getConstructor(typeToken));
}
public static <TT> TypeAdapterFactory newFactory(
final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) {
return new TypeAdapterFactory() {
@SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return typeToken.equals(type) ? (TypeAdapter<T>) typeAdapter : null;
}
};
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if(Address.class.isAssignableFrom(type.getRawType())) {
return (TypeAdapter<T>) instance;
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
ListChecker leftChecker = new ListChecker(new PropertyChecker("uri"), true);
ListChecker rightChecker = new ListChecker(new PropertyChecker("targetUri"), false);
return (TypeAdapter<T>) new EitherTypeAdapter<>(gson, EITHER_TYPE, leftChecker, rightChecker);
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (Serializable.class.equals(type.getRawType())) {
return (TypeAdapter<T>) new SerializableAdapter(gson.getAdapter(Object.class));
}
return null;
}
public GsonFactory(
Set<TypeAdapterFactory> typeAdapterFactories,
Set<TypeAdapter<?>> typeAdapters,
Set<JsonSerializer<?>> serializers,
Set<JsonDeserializer<?>> deserializers,
boolean serializeNulls
) {
this.gson = create(typeAdapterFactories, typeAdapters, serializers, deserializers, serializeNulls);
}
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final Class<? super T> rawType = type.getRawType();
if (rawType == null) {
return null;
}
if (yourType.isAssignableFrom(rawType)) {
@SuppressWarnings("unchecked")
final TypeAdapter<T> pter = (TypeAdapter<T>) createYourScalarTypeAdapter();
return pter;
} else {
return null;
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public void write(JsonWriter out, T value) throws IOException {
// Order of preference for choosing type adapters
// First preference: a type adapter registered for the runtime type
// Second preference: a type adapter registered for the declared type
// Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type)
// Fourth preference: reflective type adapter for the declared type
TypeAdapter chosen = delegate;
Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value);
if (runtimeType != type) {
TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType));
if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
// The user registered a type adapter for the runtime type, so we will use that
chosen = runtimeTypeAdapter;
} else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
// The user registered a type adapter for Base class, so we prefer it over the
// reflective type adapter for the runtime type
chosen = delegate;
} else {
// Use the type adapter for runtime type
chosen = runtimeTypeAdapter;
}
}
chosen.write(out, value);
}
@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (!Action.class.isAssignableFrom(typeToken.getRawType()))
return null;
return (TypeAdapter<T>) new ActionTypeAdapter(gson, actions);
}
public TypeAdapter create(Gson gson, TypeToken typetoken)
{
if (typetoken.getRawType() == java/util/Date)
{
return new DateTypeAdapter();
} else
{
return null;
}
}
private <A> TypeAdapter<Optional<A>> optionalAdapter(TypeAdapter<A> innerAdapter) {
return new TypeAdapter<Optional<A>>() {
@Override
public Optional<A> read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return Optional.empty();
} else {
JsonElement json = TypeAdapters.JSON_ELEMENT.read(in);
try {
A value = innerAdapter.fromJsonTree(json);
return Optional.of(value);
}
catch (JsonSyntaxException e) {
/**
* Note : This is a workaround and it only exists because salt doesn't differentiate between a
* non-existent grain and a grain which exists but has value set to empty String.
*
* If an object is expected but instead empty string comes in then we return empty Optional.
*/
if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString() &&
json.getAsString().isEmpty()) {
return Optional.empty();
}
throw e;
}
}
}
@Override
public void write(JsonWriter out, Optional<A> optional) throws IOException {
innerAdapter.write(out, optional.orElse(null));
}
};
}
@Override
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return type.getRawType() == Date.class
? (TypeAdapter<T>) new Iso8601DateTypeAdapter()
: null;
}