有些场景需要根据外部传的fields来过滤需要的字段。例如fields=name,address.city
提供两种实现方式,一个是自定义实现com.alibaba.fastjson的PropertyPreFilter,一个是自己写一个过滤的工具类。两个都可以实现按照层级过滤。
1.自定义实现com.alibaba.fastjson的PropertyPreFilter
public class FieldsPropertyPreFilter implements PropertyPreFilter {
private final Class<?> clazz;
private final Set<String> includes = new HashSet<String>();
private final Set<String> excludes = new HashSet<String>();
public FieldsPropertyPreFilter(String... properties) {
this((Class) null, properties);
}
public FieldsPropertyPreFilter(Class<?> clazz, String... properties) {
this.clazz = clazz;
for (String item : properties) {
if (item != null) {
this.includes.add(item);
}
}
}
public Set<String> getIncludes() {
return includes;
}
public Set<String> getExcludes() {
return excludes;
}
@Override
public boolean apply(JSONSerializer jsonSerializer, Object source, String fieldName) {
if (source == null) {
return true;
}
if (clazz != null && !clazz.isInstance(source)) {
return true;
}
SerialContext serialContext = jsonSerializer.getContext();
String rankName = serialContext.toString();
rankName = rankName + "." + fieldName;
//去除掉[] 如果是数组的话有有这个存在
rankName = rankName.replaceAll("\\[\\d+\\]", "");
//去除开头的$.
rankName = rankName.replace("$.", "");
if (this.excludes.contains(rankName)) {
return false;
}
if (includes.size() == 0) {
return true;
}
else {
for (String include : includes) {
if (rankName.startsWith(include)) {
return true;
}
if (include.startsWith(rankName)) {
return true;
}
}
}
return false;
}
}
使用自定义的filter
SerializeFilter[] filterArr = new SerializeFilter[1];
if (StringUtil.isNotEmpty(fields)) {
FieldsPropertyPreFilter propertyPreFilter = new FieldsPropertyPreFilter();
propertyPreFilter.getIncludes().addAll(Arrays.asList(fields.split(",")));
filterArr[0] = propertyPreFilter;
}
String httpRespContentsStr = JSON.toJSONString(httpRespContents, filterArr);
过滤的效果如下:
原始的json
[
{
"lifecycleState": "active",
"resourceSpecification": {
"name": "prepaid(gsm)",
"id": "1"
}
},
{
"lifecycleState": "active",
"resourceSpecification": {
"name": "prepaid(gsm)",
"id": "1"
}
}
]
使用字段fields=resourceSpecification.name,lifecycleState过滤,过滤后
[
{
"lifecycleState": "active",
"resourceSpecification": {
"name": "prepaid(gsm)"
}
},
{
"lifecycleState": "active",
"resourceSpecification": {
"name": "prepaid(gsm)"
}
}
]
2.完全自己实现过滤类
public class FieldsFilterHelper {
/**
*
* Description: 根据fields过滤JSONObject
*
* @author xue.chongfei<br>
* @taskId <br>
* @param json JSONObject
* @param fields String
* @return JSONObject
*/
public static JSONObject filterFields(JSONObject json, String fields) {
if (json == null) {
return new JSONObject();
}
if (StringUtil.isEmpty(fields)) {
return json;
}
Map<String, Object> fieldMap = getFieldMap(fields);
JSONObject result = filterFields(json, fieldMap);
if (CommonUtil.isEmpty(result)) {
result = json;
}
return result;
}
/**
*
* Description:根据fields过滤JSONArray
*
* @author xue.chongfei<br>
* @taskId <br>
* @param jsonArray JSONArray
* @param jsonArray JSONArray
* @return JSONArray
*/
public static JSONArray filterFields(JSONArray jsonArray, String fields) {
if (jsonArray == null) {
return new JSONArray();
}
if (StringUtil.isEmpty(fields)) {
return jsonArray;
}
// 获取fieldMap
Map<String, Object> fieldMap = getFieldMap(fields);
JSONArray result = filterFields(jsonArray, fieldMap);
if (CommonUtil.isEmpty(result)) {
result = jsonArray;
}
else {
boolean flag = isResultArrayEmpty(result);
if (!flag) {
result = jsonArray;
}
}
return result;
}
/**
*
* Description: 返回结果是否为空
*
* @author xue.chongfei<br>
* @taskId <br>
* @param jsonArray JSONArray
* @return
*/
private static boolean isResultArrayEmpty(JSONArray jsonArray) {
boolean flag = false;
for (Object jsonElement : jsonArray) {
if (jsonElement instanceof JSONObject) {
if (CommonUtil.isNotEmpty((JSONObject) jsonElement)) {
flag = true;
break;
}
}
else {
flag = true;
break;
}
}
return flag;
}
/**
*
* Description: 获取fieldMap
*
* @author xue.chongfei<br>
* @taskId <br>
* @param fields String
* @return
*/
private static Map<String, Object> getFieldMap(String fields) {
Map<String, Object> fieldMap = new HashMap<String, Object>();
String[] fieldList = fields.split(",");
for (String field : fieldList) {
field = field.replace(" ", "");
if (!(field.startsWith(".") || field.endsWith("."))) {
fillUpFieldMap(fieldMap, field);
}
}
return fieldMap;
}
public static JSONArray filterFields(JSONArray jsonArray, Map<String, Object> fieldMap) {
JSONArray resultArray = new JSONArray();
if (jsonArray == null) {
return resultArray;
}
if (CommonUtil.isEmpty(fieldMap)) {
return jsonArray;
}
JSONObject filteredJson = null;
for (Object jsonElement : jsonArray) {
if (jsonElement instanceof JSONObject) {
filteredJson = filterFields((JSONObject) jsonElement, fieldMap);
resultArray.add(filteredJson);
}
}
return resultArray;
}
public static JSONObject filterFields(JSONObject json, Map<String, Object> fieldMap) {
JSONObject result = new JSONObject();
for (Map.Entry<String, Object> entry : fieldMap.entrySet()) {
String fieldName = entry.getKey();
Object value = entry.getValue();
if (json.containsKey(fieldName)) {
Object fieldValue = json.get(fieldName);
if (value == null) {
result.put(fieldName, fieldValue);
}
else {
if (fieldValue instanceof JSONObject) {
JSONObject childResult = filterFields((JSONObject) fieldValue, (Map<String, Object>) value);
if (CommonUtil.isNotEmpty(childResult)) {
result.put(fieldName, childResult);
}
}
else if (fieldValue instanceof JSONArray) {
JSONArray childResult = filterFields((JSONArray) fieldValue, (Map<String, Object>) value);
if (CommonUtil.isNotEmpty(childResult)) {
result.put(fieldName, childResult);
}
}
else {
result.put(fieldName, fieldValue);
}
}
}
}
return result;
}
/**
*
* Description:组装FieldMap
*
* @author xue.chongfei<br>
* @taskId <br>
* @param fieldMap Map
* @param field String
*/
private static void fillUpFieldMap(Map<String, Object> fieldMap, String field) {
String[] fieldHierarchy = field.split("\\.");
String fieldName = fieldHierarchy[0];
if (fieldMap.containsKey(fieldName)) {
Object oldValue = fieldMap.get(fieldName);
if (oldValue != null) {
if (fieldHierarchy.length > 1) {
fillUpFieldMap((Map) oldValue, field.substring(fieldName.length() + 1));
}
else {
fieldMap.put(fieldName, null);
}
}
}
else {
if (fieldHierarchy.length > 1) {
fieldMap.put(fieldName, new HashMap<String, Object>(10));
fillUpFieldMap((Map) fieldMap.get(fieldName), field.substring(fieldName.length() + 1));
}
else {
fieldMap.put(fieldName, null);
}
}
}
public static void main(String[] args) {
String jsonStr = "[{\"name\": \"Alice\", \"age\": 30, \"address\": {\"city\": \"New York\", \"zipcode\": \"10001\"}}, {\"name\": \"Bob\", \"age\": 25, \"address\": {\"city\": \"San Francisco\", \"zipcode\": \"94105\"}}]";
JSONArray jsonArray = JSON.parseArray(jsonStr);
String fields = "name,address.xx.mm,address.city";
JSONArray filteredArray = filterFields(jsonArray, fields);
System.out.println(jsonStr);
System.out.println(filteredArray.toString());
}
}
使用上面这个类
String httpRespContentsStr = null;
if (httpRespContents instanceof List) {
JSONArray jsonArray = (JSONArray) JSON.toJSON(httpRespContents);
if (StringUtil.isNotEmpty(fields)) {
jsonArray = FieldsFilterHelper.filterFields(jsonArray, fields);
}
httpRespContentsStr = JSON.toJSONString(jsonArray, valuefilter);
}
else if (httpRespContents instanceof Map) {
JSONObject jsonObject = (JSONObject) JSON.toJSON(httpRespContents);
if (StringUtil.isNotEmpty(fields)) {
jsonObject = FieldsFilterHelper.filterFields(jsonObject, fields);
}
httpRespContentsStr = JSON.toJSONString(jsonObject, valuefilter);
}
else {
httpRespContentsStr = JSON.toJSONString(httpRespContents, valuefilter);
}