您可以通过使用custom无需手动取消代理所有内容
TypeAdapter。遵循以下原则:
public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> { public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { @Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson) : null); } }; private final Gson context; private HibernateProxyTypeAdapter(Gson context) { this.context = context; } @Override public HibernateProxy read(JsonReader in) throws IOException { throw new UnsupportedOperationException("Not supported"); } @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void write(JsonWriter out, HibernateProxy value) throws IOException { if (value == null) { out.nullValue(); return; } // Retrieve the original (not proxy) class Class<?> baseType = Hibernate.getClass(value); // Get the TypeAdapter of the original class, to delegate the serialization TypeAdapter delegate = context.getAdapter(TypeToken.get(baseType)); // Get a filled instance of the original class Object unproxiedValue = ((HibernateProxy) value).getHibernateLazyInitializer() .getImplementation(); // Serialize the value delegate.write(out, unproxiedValue); }}要使用它,您必须首先注册它:
GsonBuilder b = new GsonBuilder();...b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);...Gson gson = b.create();
注意,这将递归地初始化对象层次结构中的每个代理。但是由于您必须序列化整个数据,因此无论如何都应该这样做。
这是如何运作的?
GSON包含许多
TypeAdapterFactory针对各种类型(原始类型,常见类型(例如
String或)
Date,列表,数组等)的实现。询问每个工厂是否能够序列化某种Java类型(参数to
create是a
TypeToken而不是a
Class,以便捕获有关泛型的可能信息,而
Class没有泛型)。如果工厂能够序列化/反序列化类型,则它会以一个
TypeAdapter实例进行响应;否则它会以回应
null。
HibernateProxyTypeAdapter.FACTORY验证 类型 是否实现
HibernateProxy;
在这种情况下,它将返回一个实例
HibernateProxyTypeAdapter进行序列化。
write当必须对实际对象进行序列化时,将调用该方法。适配器提取基础对象的原始类型,并向GSON询问
TypeAdapter原始类型的标准,通常为
ReflectiveTypeAdapter。
然后,它检索原始类的实例,而不是直接使用代理。这是必要的,因为直接
ReflectiveTypeAdapter访问字段,而不是使用getters。访问代理对象的字段无效,这是经典的Hibernate陷阱。
作为可能的性能改进,
TypeAdapter应在
create方法中获取委托。我发现调用
getSuperclass()代理
Class似乎产生了原始基类。代码可以变成:
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { @Override @SuppressWarnings("unchecked") public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { return (HibernateProxy.class.isAssignableFrom(type.getRawType()) ? (TypeAdapter<T>) new HibernateProxyTypeAdapter((TypeAdapter)gson.getAdapter(TypeToken.get(type.getRawType().getSuperclass()))) : null); }};private final TypeAdapter<Object> delegate;private HibernateProxyTypeAdapter(TypeAdapter<Object> delegate) { this.delegate = delegate;}@SuppressWarnings({"rawtypes", "unchecked"})@Overridepublic void write(JsonWriter out, HibernateProxy value) throws IOException { if (value == null) { out.nullValue(); return; } delegate.write(out, ((HibernateProxy) value).getHibernateLazyInitializer() .getImplementation());}


