【问题标题】:Could not serialize object cause of HibernateProxy无法序列化 HibernateProxy 的对象原因
【发布时间】:2012-11-07 17:22:50
【问题描述】:

我从服务器收到以下错误响应。

HTTP 状态 500 -

输入异常报告

消息

描述服务器遇到内部错误() 它无法满足此请求。

异常

javax.servlet.ServletException: java.lang.UnsupportedOperationException:试图序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘了 注册一个类型适配器?

根本原因

java.lang.UnsupportedOperationException: 试图序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘了 注册一个类型适配器?

来自 Java 调试器:

org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@7632012e

我正在使用 Gson 将我的 Java 对象转换为 JSON。下面我粘贴了一些我的代码。

这是我的资源:

@Stateless
@LocalBean
@Path("/autos")
@Produces(MediaType.APPLICATION_JSON)
public class AutoResource {

    @EJB
    private CarAssembler warehouse;
    @Context
    private UriInfo uriInfo;

    @GET
    public Response allAutos() {
        // Building a context, lots of code...
        // Creating a Gson instance and configures it...

        final Auto auto = warehouse.list(context);
        final String autoJson = gson.toJson(auto);

        return Response.ok(autoJson).build();
    }
}

CarAssembler 只是一个调用存储库的服务。我这里没有粘贴服务的代码。

存储库:

@Override
public Question findById(final int id, final FetchType fetchType) {

    final Auto question = getEntityManager().find(Auto.class, id);

    if (fetchType == FetchType.LAZY) {
        return auto;
    }

    Hibernate.initialize(auto.getManufacturer());
    Hibernate.initialize(auto.getAssemblyHouse());

    return auto;
}

如您所见,我提供了对象的延迟加载和急切加载。我使用 Hibernate.initialize 来渴望获取 JPA 关联。但是,问题是如何修复我得到的代理错误。为什么只有AssemblyHouse仍然附加到JavaAssist,而Manufacturer没有(我在Java Debugger中看到了类型)。我如何知道何时取消代理对象?我应该取消代理该汽车可能具有的所有关联吗?在我的代码的哪一层?当我取消代理时,它会影响我的应用程序的性能吗?还有其他解决方案吗?我从错误消息中看到我可以制作类型适配器。是的,我可以,但我必须对所有域对象执行此操作,以确保正确完成转换。当我尝试将域中的其他对象也转换为 JSON 表示时,可能会开始失败,但我不知道何时或为什么。其他物体都很好,这只是运气吗?

这是我取消代理对象的方式,但我还没有实现它,因为我不知道这是好是坏,在哪一层做,什么时候做。我应该一直取消代理对象吗?

public class HibernateUtilities {

    public static <T> T unproxy(T proxy) {
        if (proxy == null) {
            return null;
        }

        if (proxy instanceof HibernateProxy) {
            Hibernate.initialize(proxy);

            HibernateProxy hibernateProxy = (HibernateProxy) proxy;
            T unproxiedObject = (T) hibernateProxy.getHibernateLazyInitializer().getImplementation();

            return unproxiedObject;
        }

        return proxy;
    }
}

按要求进行堆栈跟踪:

[#|2012-11-22T17:17:13.285+0100|警告|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=71;_ThreadName=Thread-8;| StandardWrapperValve [javax.ws.rs.core.Application]: PWC1406:Servlet javax.ws.rs.core.Application 的 Servlet.service() 抛出异常 java.lang.UnsupportedOperationException: 试图 序列化 java.lang.Class:org.hibernate.proxy.HibernateProxy。忘记 注册一个类型适配器? 在 com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:64) 在 com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:61) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.ArrayTypeAdapter.write(ArrayTypeAdapter.java:93) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96) 在 com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) 在 com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 在 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 在 com.google.gson.Gson.toJson(Gson.java:586) 在 com.google.gson.Gson.toJson(Gson.java:565) 在 com.google.gson.Gson.toJson(Gson.java:520) 在 com.myapp.AutoResource.produceAuto(AutoResource.java:48) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:601) 在 org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052) 在 org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124) 在 com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388) 在 com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619) 在 com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) 在 com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571) 在 com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162) 在 com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:601) 在 com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861) 在 com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800) 在 com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370) 在 com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360) 在 com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348) 在 com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214) 在 com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:601) 在 com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) 在 com.sun.jersey.server.impl.model.method.dispatch.Abs​​tractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) 在 com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 在 com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) 在 com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 在 com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 在 com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469) 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) 在 com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:770) 在 org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 在 org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 在 org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 在 org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:161) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) 在 org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 在 com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 在 com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 在 com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 在 com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 在 com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 在 com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 在 com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 在 com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 在 com.sun.grizzly.ContextTask.run(ContextTask.java:71) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 在 java.lang.Thread.run(Thread.java:722) |#]

【问题讨论】:

  • 您还记得当您学习如何构建应用程序时,有人向您解释了分层的想法。当你在同一个类中混合表示、业务和数据库逻辑时会发生这种情况(那些注释将逻辑泄漏到你的类中,它们并不像你想象的那么透明)
  • @Augusto 你认为sn-ps的代码都来自同一个类吗?
  • 我不完全相信您的问题出在Manufacturer。尝试用final String autoJson = gson.toJson(auto, Auto.class);序列化,如果不行,能贴出堆栈跟踪吗?
  • 它是调试器中唯一属于 HibernateProxy 类型的类,这就是问题所在。当我从序列化中排除此属性时,它也很有效。
  • 从堆栈跟踪看来,您在数组中遇到了一些问题,在层次结构中较低。你能验证它是什么吗?

标签: java hibernate jakarta-ee jax-rs gson


【解决方案1】:

您无需手动取消代理,只需使用自定义TypeAdapter。 大致如下:

/**
 * This TypeAdapter unproxies Hibernate proxied objects, and serializes them
 * through the registered (or default) TypeAdapter of the base class.
 */
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 实现,适用于各种类型(原始类型、StringDate 等常见类型、列表、数组...)。询问每个工厂是否能够序列化某个 Java 类型(create 的参数是 TypeToken 而不是 Class,以便捕获有关泛型类型的可能信息,Class 没有) .如果工厂能够序列化/反序列化一个类型,它会以TypeAdapter 实例响应;否则它会回复null

HibernateProxyTypeAdapter.FACTORY 验证type 是否实现HibernateProxy;在这种情况下,它会返回一个HibernateProxyTypeAdapter 的实例以进行序列化。 write 方法在需要序列化实际对象时调用;适配器提取底层对象的原始类型,向GSON询问原始类型的标准TypeAdapter,一般为ReflectiveTypeAdapter

然后它检索原始类的实例,而不是直接使用代理。这是必要的,因为ReflectiveTypeAdapter 访问directly to fields,而不是使用getter;访问代理对象的字段不起作用,并且是经典的Hibernate pitfall

作为一种可能的性能改进,应在create 方法中获取委托TypeAdapter。我发现在代理 Class 上调用 getSuperclass() 似乎会产生原始基类。那么代码就可以变成:

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"})
@Override
public void write(JsonWriter out, HibernateProxy value) throws IOException {
    if (value == null) {
        out.nullValue();
        return;
    }
    delegate.write(out, ((HibernateProxy) value).getHibernateLazyInitializer()
            .getImplementation());
}

【讨论】:

  • 我有时间测试和修复它,用当前代码再试一次。
  • 太棒了!你介意解释一下你的一些代码和评论吗?这个适配器只会在将要被序列化为 HibernateProxy 类型的对象时触发,对吧? gson 是否为要序列化的每个对象找到匹配的类型适配器?
  • 我在代码中添加了一些 cmets,以及一个(有些冗长的)解释!
  • 这是一个相当古老的答案,但只是想我会发表评论。当我传递单个对象时,此代码会导致堆栈溢出异常。它适用于序列化List 类型。
  • @Flavio 感谢您的回答,但它给了我堆栈溢出!
【解决方案2】:

好像您提到过急切加载仍然存在错误,那么问题可能不是 Hibernate,而是可能在 GSON 实现上。我认为您在创建 JSON 时需要一个类型,不确定它是否已注册,但可能是这样的:

public String autosToJson(Auto autos) {  
    GsonBuilder gsonBuilder = new GsonBuilder();
    Gson gson = gsonBuilder.registerTypeAdapter(Auto.class, new AutoAdapter()).create();
    return gson.toJson(autos);
}   

然后只需创建一个AdapterClass,例如:

public class AutoAdapter implements JsonSerializer<Auto> {
  @Override
  public JsonElement serialize(Auto auto, Type type, JsonSerializationContext jsc) {
    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("auto_id", auto.getId());
    jsonObject.addProperty("auto_name", auto.getAutoName());
    jsonObject.addProperty("auto__manufacture_date", auto.getManufactureDate().toString());
    return jsonObject;      
  }
}

【讨论】:

  • 错误是事件虽然调用了Hibernate.initialize(auto.getManufacturer());,但getter返回的Manufacturer对象仍然是HibernateProxy。我在调试应用程序时看到了这一点。但是另一个对象不是HibernateProxy
  • 我可以单独添加属性并在需要时对其进行转换,这正是我所寻找的。谢谢!
【解决方案3】:

在通常情况下,您不希望您的域对象通过服务公开为 XML/JSON,通常您需要创建一个 DTO,因为您的实体不符合您的消费者的需求。即使现在可以,在对数据库进行内部重构之后,明天也无法适应。因此,如果您遇到这样的麻烦,我的建议是立即创建 DTO。顺便说一句,您甚至可以在 Hibernate 级别上创建这些 DTO,方法是使用结果转换器或创建视图并将 Hibernate 实体映射到这些视图上。

另一个技巧是使用Dozer 将所需字段复制到另一个类(实际上是相同的类,但没有代理)。

请注意:您使用的是 Gson,它访问您的 字段,而不是访问器,这使得 Hibernate 代理无法使用,因为它将尝试访问代理本身的字段总是null

【讨论】:

    【解决方案4】:

    是的,你可以一直取消代理,如果它有一个 HibernateProxy(它不会序列化),它将消失并替换为实际的底层实现,或者它将保持原样并给你一个实现.我认为您的解决方案应该可以正常工作。请注意,我并没有真正使用 Hibernate,但它对我来说确实有意义。

    另一方面,您可能更信任 Hibernate,但更简单的方法可能是:

    Hibernate.getClass(obj);
    

    此解决方案不应为您提供已实现/初始化的类,仅提供该类,或者该功能应由以下人员提供:

    HibernateProxyHelper.getClassWithoutInitializingProxy(superClass)
    

    我相信后者可能会返回超类,所以你可以从 Hibernate.getClass(obj); 开始

    还有:

    public static <T> T initializeAndUnproxy(T entity) {
        if (entity == null) {
            throw new 
               NullPointerException("Entity passed for initialization is null");
        }
    
        Hibernate.initialize(entity);
        if (entity instanceof HibernateProxy) {
            entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
                    .getImplementation();
        }
        return entity;
    }
    

    上面的代码是从Converting Hibernate proxy to real object借来的,其中的变量名可能更好,因为它们并不意味着实体总是代理。它也会抛出一个异常来警告你,但你是否想要这个异常取决于你。

    当然你也可以摆脱延迟加载,但我认为这不是最好的解决方案。

    【讨论】:

    • 那么,取消代理对象是否会由于某种原因导致大量性能问题?我是否应该一直取消代理存储库中的所有对象以防止遇到此问题?
    • 这是一个很好的问题,绝对是针对 Hibernate Staff 的。话虽如此,我的意见如下:这取决于您需要序列化多少次(即:它被调用的频率)。需要实例化多少对象(定期序列化的对象中有多少具有代理,lazyinit)。最坏的情况是,它并不比在创建时实例化所有对象更糟糕。
    • 如果你真的需要优化你可以返回Hibernate.getClass(obj),这将是一个类对象,而不是一个实例化的对象。
    • 急切加载似乎并没有取消代理对象,因为我已经使用了Hibernate.initialize(..)
    【解决方案5】:

    尝试通过ObjectMapper解析为

    final Auto auto = warehouse.list(context);
    final String autoJson = new ObjectMapper().writeValueAsString(auto);
    
    return Response.ok(autoJson).build();
    

    【讨论】:

      【解决方案6】:

      当我碰到这篇文章时,我遇到了这个问题,它为我的情况指明了正确的方向。我意识到我不需要序列化整个实体,特别是因为我将一些字段标记为延迟加载。所以我试图找到一种跳过这些字段的方法,而 ExclusionStrategy 很神奇。这似乎解决了我的问题

      public class ExcludeProxiedFields implements ExclusionStrategy{
      
          @Override
          public boolean shouldSkipField(FieldAttributes fa) {
              return fa.getAnnotation(ManyToOne.class) != null ||
                 fa.getAnnotation(OneToOne.class) != null  ||
                 fa.getAnnotation(ManyToMany.class) != null  ||
                 fa.getAnnotation(OneToMany.class) != null ;
          }
      
          @Override
          public boolean shouldSkipClass(Class<?> type) {
              return false;
          }   
      }
      

      然后我像这样将这个类应用到 GsonBuilder:

      Gson gson = new GsonBuilder().setExclusionStrategies(new ExcludeProxiedFields()).create();
      

      【讨论】:

        猜你喜欢
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 2014-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-04
        • 2018-04-25
        相关资源
        最近更新 更多