从网络流量考虑,我们的远程接口有时并不需要返回所有数据。为此,可以通过反射去掉不要的属性。
/**
* 过滤属性,省流量
*
*
* @param bean
* @param filter
*/
public static void filterProps(Object bean,
ResultPropsFilter filter) {
if (filter == null) {
return;
}
PropertyDescriptor[] pdArray = PropertyUtils
.getPropertyDescriptors(bean);
if (pdArray == null) {
return;
}
for (PropertyDescriptor pd : pdArray) {
String propName = pd.getName();
if(propName.equals("class")){
continue;
}
Class<?> type = pd.getPropertyType();
// 原子类型不支持null, 无法过滤。这也意味着应该尽量使用封装类型,而不是原子类型
if (type.isPrimitive()) {
continue;
}
if (!filter.isPropIncluded(propName)) {
// 不需要去掉
continue;
}
String errIfFail = "cannot set property " + propName + " to null";
try {
PropertyUtils.setProperty(bean, propName, null);
} catch (IllegalAccessException e) {
logger.error(errIfFail, e);
} catch (InvocationTargetException e) {
logger.error(errIfFail, e);
} catch (NoSuchMethodException e) {
logger.error(errIfFail, e);
}
}
}
public abstract class ResultPropsFilter {
public static final String FILTER_MODE_INCLUDE = "INCL";
public static final String FILTER_MODE_EXCLUDE = "EXCL";
/**
* 返回结果属性过滤模式。如果为INCL,则服务端会忽略excludeProps; 如果为EXCL,则服务端会忽略includeProps;
* 默认情况下为EXCL模式且excludeProps为空,意味着服务端返回所有值
*/
private String filterMode = FILTER_MODE_EXCLUDE;
/**
* 需要包含的属性。
*/
private List<String> includeProps;
/**
* 需要排除的属性。
*/
private List<String> excludeProps;
public boolean isPropIncluded(String prop) {
if (FILTER_MODE_INCLUDE.equals(filterMode)) {
return getIncludeProps().contains(prop);
}
if (FILTER_MODE_EXCLUDE.equals(filterMode)) {
return !getExcludeProps().contains(prop);
}
return false;
}
...
}