1. 程式人生 > >FastJson轉JSON 引用問題

FastJson轉JSON 引用問題

在中Hibernate開發中,用FastJson轉JSON,由於類定義的物件,所以查詢到的子物件有相同的,這時FastJSON,在

轉JSON時,會把已經有的JSON物件,用引用$,ref表示,網上查到說把FastJSON禁止引用,SerializerFeature.DisableCircularReferenceDetect 
當開啟這個屬性時JAVA,會出現Stack溢位的報錯。 
沒有一個靠譜的,可以重寫FastJSON中的PropertyPreFilter類,然後指明要轉JSON的欄位,就不會出現Stack溢位的報錯,廢話不多說。
以下為重寫工具類

public class ComplexPropertyPreFilter implements PropertyPreFilter {

/**
 * @Fields includes : TODO(包含的屬性)
 */
private Map<Class<?>, String[]> includes = new HashMap<Class<?>, String[]>();

/**
 * @Fields excludes : TODO(不包含的屬性)
 */
private Map<Class<?>, String[]> excludes = new HashMap<Class<?>, String[]>();

static {
    JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect
            .getMask();
}

public ComplexPropertyPreFilter() {

}

public ComplexPropertyPreFilter(Map<Class<?>, String[]> includes) {
    super();
    this.includes = includes;
}

public boolean apply(JSONSerializer serializer, Object source, String name) {

    // 物件為空。直接放行
    if (source == null) {
        return true;
    }

    // 獲取當前需要序列化的物件的類物件
    Class<?> clazz = source.getClass();

    // 無需序列的物件、尋找需要過濾的物件,可以提高查詢層級
    // 找到不需要的序列化的型別
    for (Map.Entry<Class<?>, String[]> item : this.excludes.entrySet()) {
        // isAssignableFrom(),用來判斷型別間是否有繼承關係
        if (item.getKey().isAssignableFrom(clazz)) {
            String[] strs = item.getValue();

            // 該型別下 此 name 值無需序列化
            if (isHave(strs, name)) {
                return false;
            }
        }
    }

    // 需要序列的物件集合為空 表示 全部需要序列化
    if (this.includes.isEmpty()) {
        return true;
    }

    // 需要序列的物件
    // 找到不需要的序列化的型別
    for (Map.Entry<Class<?>, String[]> item : this.includes.entrySet()) {
        // isAssignableFrom(),用來判斷型別間是否有繼承關係
        if (item.getKey().isAssignableFrom(clazz)) {
            String[] strs = item.getValue();
            // 該型別下 此 name 值無需序列化
            if (isHave(strs, name)) {
                return true;
            }
        }
    }

    return false;
}

/*
 * 此方法有兩個引數,第一個是要查詢的字串陣列,第二個是要查詢的字元或字串
 */
public static boolean isHave(String[] strs, String s) {

    for (int i = 0; i < strs.length; i++) {
        // 迴圈查詢字串陣列中的每個字串中是否包含所有查詢的內容
        if (strs[i].equals(s)) {
            // 查詢到了就返回真,不在繼續查詢
            return true;
        }
    }

    // 沒找到返回false
    return false;
}

public Map<Class<?>, String[]> getIncludes() {
    return includes;
}

public void setIncludes(Map<Class<?>, String[]> includes) {
    this.includes = includes;
}

public Map<Class<?>, String[]> getExcludes() {
    return excludes;
}

public void setExcludes(Map<Class<?>, String[]> excludes) {
    this.excludes = excludes;
}
}
以下為具體工具類的呼叫方式
complexPropertyPreFilter complexPropertyPreFilter = new ComplexPropertyPreFilter();
			complexPropertyPreFilter
					.setIncludes(new HashMap<Class<?>, String[]>() {
						private static final long serialVersionUID = -8411128674046835592L;
						{
							put(Tree.class, new String[] { "id", "text", "pid",//要顯示的屬性欄位
									"checked", "paramType", "paramObject" });
							put(String.class, new String[] { "loaderName" });
						}
					});
			super.getResponse()
					.getWriter()
					.print(JSON.toJSONString(this.getTree(departmentList),
							complexPropertyPreFilter,
							SerializerFeature.WriteNullStringAsEmpty,
							SerializerFeature.WriteNullListAsEmpty));

本文轉自  CSDN 使用者   Nothing  http://write.blog.csdn.net/postedit/50963462