restful接口处理返回的json

针对前后端分离时,返回给前端的json格式的数据需要处理

  • 处理规则
    • String类型由null修改为返回“”
    • List类型由null修改为[ ]

实现源码

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

@Aspect
@Component
public class JsonFormatAspect {

    // 切入点,*表示通配符,..表示多个通配符
    @Pointcut("execution(* com.zkane..controller.*.*(..))")
    private void jsonFormat() {
    }

    // 返回数据的切面
    @AfterReturning(returning = "obj", pointcut = "jsonFormat()")
    public void doAfterReturning(Object obj) throws IllegalAccessException {
        if (obj != null) {
            formatJson(obj);
        }
    }

    // 缓存不需要处理的对象
    private static List<Class> classList;

    static {
        classList = new ArrayList<>();
        classList.add(Short.class);
        classList.add(Integer.class);
        classList.add(Float.class);
        classList.add(Long.class);
        classList.add(Double.class);
        classList.add(String.class);
        classList.add(Boolean.class);
        classList.add(Date.class);
    }

    private void formatJson(Object obj) throws IllegalAccessException {
        // 不处理classList中的类型和基本数据类型
        if (classList.contains(obj.getClass()) || obj.getClass().isPrimitive()) {
            return;
        }
        Field[] fields = getAllFields(obj);
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            // 判断是否为String的类型或子类
            if (String.class.isAssignableFrom(field.getType())) {
                if (value == null) {
                    field.set(obj, "");
                }
                continue;
            }
            // 判断是否为Collection的类型或子类
            if (Collection.class.isAssignableFrom(field.getType()) || (value != null && value instanceof Collection)) {
                if (value == null) {
                    field.set(obj, new ArrayList<>());
                } else {
                    Collection collection = (Collection) value;
                    for (Object o : collection) {
                        // 递归处理对象中的属性
                        formatJson(o);
                    }
                }
                continue;
            }
            if (value != null) {
                // 递归处理对象中的属性
                formatJson(value);
            }
        }
    }

    // 获取所有属性,包括从父类的属性
    private Field[] getAllFields(Object obj) {
        List<Field> fieldList = new ArrayList<>();
        Class clazz = obj.getClass();
        while (clazz != null) {
            // 只会获取本类中的所有属性,不会获取父类中的属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                fieldList.add(field);
            }
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }
}

优化后的代码

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 规则:String对象为null时,修改为"";集合为null时,new一个新集合(集合目前只支持List和Set)
 */
@Aspect
@Component
public class JsonFormatAspect {

    @Pointcut("execution(* com.zkane..controller.*.*(..))")
    private void jsonFormat() {
    }

    @AfterReturning(returning = "obj", pointcut = "jsonFormat()")
    public void doAfterReturning(Object obj) throws Exception {
        formatJson(obj);
    }

    private void formatJson(Object obj) throws Exception {
        // 优化的地方,只处理自己定义的类中的属性
        final String className = "com.zkane";
        if (obj == null || !obj.getClass().getName().contains(className)) {
            return;
        }
        Field[] fields = getAllFields(obj);
        for (Field field : fields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            // 判断是否为String的类型或子类
            if (String.class.isAssignableFrom(field.getType())) {
                if (value == null) {
                    field.set(obj, "");
                }
                continue;
            }
            // 判断是否为Collection的类型或子类。用value判断是因为有些属性设置为Object,前面那个判断无法判断为集合类型
            boolean isCollection = Collection.class.isAssignableFrom(field.getType()) || (value != null && value instanceof Collection);
            if (isCollection) {
                // 只判断了List和Set,需要保证bean中的属性用的是List和Set类型,而不是具体实现类。后续可以加上对数组的判断Class.siArray。jdk使用java.lang.reflect.Array.newInstance(type.getComponentType(), 0);生成数组对象
                if (value == null) {
                    if (List.class.isAssignableFrom(field.getType())) {
                        field.set(obj, new ArrayList());
                    }
                    if (Set.class.isAssignableFrom(field.getType())) {
                        field.set(obj, new HashSet());
                    }
                } else {
                    Collection collection = (Collection) value;
                    for (Object o : collection) {
                        // 递归处理集合中的每个元素
                        formatJson(o);
                    }
                }
                continue;
            }
            // 递归处理对象的属性
            formatJson(value);
        }
    }

    /**
     * 获取对象的所有属性,包括父类中的属性。在获取父类时,也可以判断父类是不是自己定义的类。但是一般bean只有Object是jdk的类,Object中没有属性,所以不会影响。
     */
    private Field[] getAllFields(Object obj) {
        List<Field> fieldList = new ArrayList<>();
        Class clazz = obj.getClass();
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                fieldList.add(field);
            }
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值