在开发WEB应用中,我们需要经常输出JSON给到前端,比较直接的做法是直接返回实体,如 return new User()
,但这使我们把User的所有属性全部输出,这其中难免会有敏感信息,并且有部分信息前端根本用不上。虽然有些类库可以通过注解标明输出时忽略某些属性渲染,但有时某个属性在这不需要输出,在另一个地方却可能需要输出。
最终我写了个工具类来解决这个问题,不当之处还请指出:
public class AttributesExtractUtils {
private static Logger LOGGER = LogManager.getLogger(AttributesExtractUtils.class);
/**
* 从集合中提取信息
*
* @param targets
* @param targetFields
* @return
*/
public static List<Map<String, Object>> extractForCollection(Collection<?> targets, String... targetFields) {
List<Map<String, Object>> result = new ArrayList<>();
for (Object target : targets) {
result.add(extract(target, targetFields));
}
return result;
}
/**
* 从普通POJO类中提取关键信息, 要求遵循 getMethod 规范
*
* @param target 目标JAVA POJO类,要求装有数据
* @param targetFields 类的属性名字: 希望从 POJO 中提取哪些字段的数据
* @return 数据会被装载于MAP中
*/
public static Map<String, Object> extract(Object target, String... targetFields) {
if ((null == target) || null == targetFields || 0 == targetFields.length) {
return new HashMap<>();
}
Map<String, Object> objectMap = new HashMap<>();
for (String targetField : targetFields) {
Class<?> targetClass = target.getClass();
try {
Field field = targetClass.getDeclaredField(targetField);
String methodNamePrefix = field.getType().getName().equals("boolean") ? "is" : "get";
String methodName = methodNamePrefix + String.valueOf(targetField.charAt(0)).toUpperCase()
+ targetField.substring(1);
Method targetMethod = targetClass.getMethod(methodName);
Object invoke = targetMethod.invoke(target);
objectMap.put(getNameOfElegant(targetField), invoke);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
return objectMap;
}
private static String getNameOfElegant(String old) {
StringBuilder stringBuilder = new StringBuilder();
for (char c : old.toCharArray()) {
if (Character.isUpperCase(c) && stringBuilder.length() > 0) {
stringBuilder.append("_");
}
stringBuilder.append(c);
}
return stringBuilder.toString().toLowerCase();
}
public static void main(String[] args) {
// System.out.println(getNameOfElegant("AbcDef"));
// System.out.println(getNameOfElegant("abcDefXlA"));
ModelExample lisi = new ModelExample();
lisi.setFirstName("李");
lisi.setLastName("四");
lisi.setGender(1);
lisi.setRegisterTime(System.currentTimeMillis());
ModelExample zhangsan = new ModelExample();
zhangsan.setFirstName("张");
zhangsan.setLastName("三");
zhangsan.setGender(0);
zhangsan.setRegisterTime(System.currentTimeMillis() - 86400000);
// 从单个对象中提取
Map<String, Object> lisiExtracted = AttributesExtractUtils.extract(lisi, "firstName", "lastName");
System.out.println("lisiExtracted = " + lisiExtracted);
// 从集合中提取
List<ModelExample> users = new ArrayList<>(Arrays.asList(lisi, zhangsan));
List<Map<String, Object>> usersExtracted = AttributesExtractUtils
.extractForCollection(users, "lastName", "registerTime");
System.out.println("usersExtracted = " + usersExtracted);
}
private static class ModelExample {
private String firstName;
private String lastName;
private int gender;
private long registerTime;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public long getRegisterTime() {
return registerTime;
}
public void setRegisterTime(long registerTime) {
this.registerTime = registerTime;
}
}
}```
最终 `public static void main(String[] args) { // .. }` 将输出:
lisiExtracted = {first_name=李, last_name=四}
usersExtracted = [{register_time=1465541775993, last_name=四}, {register_time=1465455375993, last_name=三}]
网友评论