flexjsonの使い方と拡張
5013 ワード
個人的にはflexjsonが本当に好きで、効率的に効率的に吹き飛ばすjsonシーケンス化ツールとは比較できませんが、jsonシーケンス化の柔軟性の上で、ソフトウェア全体の構造上と拡張の利便性の上で比類がありません.
flexjsonの使い方:
flexjsonがjsonを逆シーケンス化する場合
ArrayList
new JSONSerialize.use("values",Bean.class).deserialize(list);
1つのbeanの個別属性のみが必要で、他の属性が必要でない場合は、1つずつ除外する必要はありません.
使用可能
new JSONSerializer().include("propA").exclude("*")
new JSONSerializer().include("a.b").exclude("a.*")
また、シーケンス化には特別なニーズが必要になる場合があります.hibernateがオブジェクトに関連付けられている場合、flexjsonはシーケンス化時に1対多で完璧に解決されていますが、複数対1の場合はデフォルトで解決されず、一つ一つ排除する必要があります.
また、jsonはシーケンス化時に、複数の関連するクラスから要素を取得する必要がある場合や、サブクラスがシーケンス化時に親クラスの要素などを必要とする場合があります.
flexjsonのObjectTransformerを書き換えることで解決できます.
中のTypeTransformerMapは後に登録されたオブジェクトタイプがchildのみなので、反射でその方法を変更し、ObjectTransformerにいくつかのイベントを追加しました.json中のpathによりろ過処理等を行った.
public void transform(Object object) {
JSONContext context = getContext();
Path path = context.getPath();
ChainedSet visits = context.getVisits();
String pathStr = "";
List<String> pathList = path.getPath();
if (!pathList.isEmpty()) {
pathStr = StringUtils.join(pathList, ".");
}
try {
if (!visits.contains(object)) {
context.setVisits(new ChainedSet(visits));
context.getVisits().add(object);
// traverse object
BeanAnalyzer analyzer = BeanAnalyzer.analyze(resolveClass(object));
TypeContext typeContext = context.writeOpenObject();
for (BeanProperty prop : analyzer.getProperties()) {
String name = prop.getName();
path.enqueue(name);
//
String currPropPath = pathStr + name;
PropertyFilter propertyFilter = propertyFilterMap.get(currPropPath);
if (propertyFilter == null && propertyProcesserMap.get(currPropPath) == null) {
propertyFilter = propertyFilterMap.get("*");
}
if (propertyFilter != null && propertyFilter.isFilter(prop, path, object, context, typeContext)) {
path.pop();
continue;
}
if (context.isIncluded(prop)) {
Object value = prop.getValue(object);
//
PropertyProcesser propertyProcesser = propertyProcesserMap.get(currPropPath);
if (propertyProcesser != null) {
value = propertyProcesser.propertyProcesser(prop, value, path, object, context, typeContext);
}
if (!context.getVisits().contains(value)) {
TransformerWrapper transformer = (TransformerWrapper) context.getTransformer(value);
if (!transformer.isInline()) {
if (!typeContext.isFirst()) context.writeComma();
typeContext.setFirst(false);
context.writeName(name);
}
typeContext.setPropertyName(name);
transformer.transform(value);
}
}
path.pop();
}
//
if (!objectProcesserMap.isEmpty()) {
ObjectProcesser objectProcesser = objectProcesserMap.get(pathStr);
if (objectProcesser != null) {
objectProcesser.objectProcesser(object, path, context, typeContext);
}
}
context.writeCloseObject();
context.setVisits((ChainedSet) context.getVisits().getParent());
}
} catch (JSONException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
// throw new JSONException("Error trying to deepSerialize", e);
}
}
具体的なコードはhttps://github.com/huanwuji/springbase/tree/master/src/main/java/com/huanwuji/utils/flexJson中
テストクラス:
書き方のみ、テストクラスは
https://github.com/huanwuji/springbase/blob/master/src/test/com/huanwuji/tools/codeBatchCreate/FlexJsonTest.javaに表示されます.