Java Gson排除策略和自定义序列化

Java Gson排除策略和自定义序列化,java,gson,Java,Gson,我在持久对象上使用Gson自定义序列化。同时,我还使用了序列化排除策略。代码如下所示: public class GsonFactory { public static Gson build(Type type, final List<String> fieldExclusions, final List<Class<?>> classExclusions) { GsonBuilder gsonBuilder

我在持久对象上使用Gson自定义序列化。同时,我还使用了序列化排除策略。代码如下所示:

public class GsonFactory {

    public static Gson build(Type type, final List<String> fieldExclusions,
            final List<Class<?>> classExclusions) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() {
            public boolean shouldSkipField(FieldAttributes f) {
                return fieldExclusions == null ? false : fieldExclusions
                        .contains(f.getName());
            }

            public boolean shouldSkipClass(Class<?> clazz) {
                return classExclusions == null ? false : classExclusions
                        .contains(clazz);
            }
        });
        // Uncommenting this line will produce error
        // gsonBuilder.registerTypeAdapter(type,
        // new PersistentObjectJsonSerializer());
        return gsonBuilder.create();
    }
}

class PersistentObjectJsonSerializer implements
        JsonSerializer<PersistentObject> {

    public JsonElement serialize(PersistentObject src, Type typeOfSrc,
            JsonSerializationContext context) {
        src.setDT_RowId(src.getId());
        Gson gson = new Gson();
        return gson.toJsonTree(src);
    }

}
我的PersistentObject java类:

@MappedSuperclass
public abstract class PersistentObject implements Serializable {

....

@Transient
protected long DT_RowId;
// getters, setters not shown

...

}
这就是我如何调用GsonFactory.build-in-generichbernatedao的方法:

public abstract class GenericHibernateDAO<T, ID extends Serializable> {

private Class<T> persistentClass;

@SuppressWarnings("unchecked")
public GenericHibernateDAO() {
    this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
}


public String listAsJsonResponse(){
    ...
    // testing start
    List<Class<?>> classExclusions = new ArrayList<Class<?>>();
    classExclusions.add(Role.class);
    List<String> fieldExclusions = new ArrayList<String>();
    fieldExclusions.add("users");
    fieldExclusions.add("password");
    Gson gson = GsonFactory.build(persistentClass,fieldExclusions, null);
    ...
    return jsonResponse.toString();
}
}

基本上我无法同时使用这两个功能。任何关于什么可能导致此问题的指针?

Gson是开源的,您可以获得源代码。为什么不这样做,然后按照代码查看它在哪一点抛出异常?似乎格森陷入了一个无限循环。确实,gson经常使用递归。如果它实际上是一个bug,你可以向Gson的人报告,他们将在下一个版本中解决它


这是一个老问题,但也许我的回答仍然可以帮助别人

在序列化程序中创建一个新的Gson对象。这个Gson对象不再知道持久对象的排除策略。如果您的PersistantObject具有属性对象,这将再次导致PersistentObject(在您的情况下,用户可能具有PersistantObject的属性),那么您将运行一个无休止的循环并进入stackoverflow异常

一种解决方案是再次向序列化程序中的gson对象添加排除策略。但是不要再次将序列化程序添加到此gson对象

class PersistentObjectJsonSerializer implements
    JsonSerializer<PersistentObject> {

    public JsonElement serialize(PersistentObject src, Type typeOfSrc,
        JsonSerializationContext context) {
        src.setDT_RowId(src.getId());
        Gson gson = new Gson();
        //add exclusion strategy here again
        return gson.toJsonTree(src);
    }

}
类PersistentObject JSONSerializer实现
JsonSerializer{
公共JsonElement序列化(PersistentObject src,类型typeOfSrc,
JsonSerializationContext(上下文){
src.setDT_RowId(src.getId());
Gson Gson=新的Gson();
//再次在此处添加排除策略
返回gson.toJsonTree(src);
}
}

请提供有关PersientObject类的更多信息。这是从哪里来的(自定义类/某些库)?另外,请发布您如何调用构建方法(参数)。您似乎不是唯一一个有gson StackOverflower问题的人:此外,在另一份报告中:即使承认存在导致StackOverflow的递归,我的建议是尝试java中的其他Json库。我推荐:Jackson()@Marek Dec:我已经更新了code@Peter当前位置今晚我会试试杰克逊,然后带着结果回来
@Repository
public class UserDAO extends GenericHibernateDAO<User, Long> {

}
class PersistentObjectJsonSerializer implements
    JsonSerializer<PersistentObject> {

    public JsonElement serialize(PersistentObject src, Type typeOfSrc,
        JsonSerializationContext context) {
        src.setDT_RowId(src.getId());
        Gson gson = new Gson();
        //add exclusion strategy here again
        return gson.toJsonTree(src);
    }

}