java后端fastJson返回json的两种处理方法,自定义消息转换器(适用于全局),定义aop拦截(适用于局部)

场景:业务需要返回的json中,为null的字段也要返回,字符串赋值“”,数值赋值0.

项目中用的是springboot

处理前:

{
            "createdAt": "2019-03-27 22:01:39",
            "entId": "1"
}

处理后:

{
            "basIsEnabled": "",
            "createdAt": "2019-03-27 22:01:39",
            "creatorCode": "",
            "creatorName": "",
            "creatorOrgCode": "",
            "deleted": "1",
            "dualOrgCode": "",
            "dualOrgId": "",
            "dualOrgName": "",
            "entId": "1"
}

网上的做法一般是自定义一个消息转换器,这里我就不多介绍,主要是通过config.setSerializerFeatures实现

@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {

    /**
     * 自定义FastJon转换Api返回对象
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        converter.setSupportedMediaTypes(
                Arrays.asList(
                        new MediaType("application", "json", UTF8),
                        new MediaType("application", "*+json", UTF8)));
        // 自定义配置,不序列化class属性
        FastJsonConfig config = new FastJsonConfig();
        PropertyPreFilter classFilter =
                new PropertyPreFilter() {

                    @Override
                    public boolean apply(JSONSerializer serializer, Object object, String name) {
                        if (CLASS.equalsIgnoreCase(name)) {
                            return false;
                        }
                        return true;
                    }
                };
        SerializeConfig mapping = new SerializeConfig();
        mapping.put(Date.class, new SimpleDateFormatSerializer(DATE_FORMAT));
        mapping.put(java.sql.Date.class, new SimpleDateFormatSerializer(DATE_FORMAT));
        mapping.put(Timestamp.class, new SimpleDateFormatSerializer(DATE_TIME_FORMAT));
        config.setSerializeConfig(mapping);
        config.setSerializeFilters(classFilter);
        converter.setFastJsonConfig(config);
        converters.add(converter);
//主要配置在这
        config.setSerializerFeatures(
                SerializerFeature.WriteNullStringAsEmpty, //转字符串
                SerializerFeature.WriteNullListAsEmpty,  //转list
                SerializerFeature.WriteNullNumberAsZero, //转数值
                SerializerFeature.WriteNullBooleanAsFalse //转boolean
        );
        // 处理JSON转换Pageable分页参数
        ParserConfig.global.putDeserializer(
                Pageable.class,
                new JavaBeanDeserializer(ParserConfig.global, PageParam.class));
    }

}

但是这种做法是全局的转换,也就是说所有的接口返回都会转。如果只需要部分接口做转换,就需要用aop

思路:定义一个aop,在返回响应体的时候对output进行处理,定义一个注解作为pointcut,这样只要在方法上加上了这个注解,都会进行返回值的处理

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ReturnJsonDiversion {
    String value() default "";
}
@Aspect
@Component
public class RetrunJsonAspect {

    /**
     *  @After (后置通知)
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @AfterReturning(pointcut = "@annotation(com.pagoda.intfc.api.aop.ReturnJsonDiversion)", returning = "returnValue")
    public Object after(JoinPoint point, Object returnValue) {
        ReturnResult returnResult = (ReturnResult) returnValue;
        if (returnResult.getData() instanceof List) {
            List<Object> dataList = (List) returnResult.getData();
            dataList.forEach(o -> {
                try {
                    Map<String, Field> objectMap = objMap(o);
                    for(Map.Entry<String,Field> m: objectMap.entrySet()) {
                        Object obj = m.getValue().get(o);
                        Class<?> clazz = m.getValue().getType();
                        if(Objects.isNull(obj)) {
                            if (clazz == Date.class || clazz == String.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, "");
                            } else if (clazz == BigDecimal.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, new BigDecimal(0));
                            } else if (clazz == Integer.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, Integer.valueOf(0));
                            } else if (clazz == Float.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, Float.valueOf(0));
                            } else if (clazz == Double.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, Double.valueOf(0));
                            } else if (clazz == Long.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, Long.valueOf(0));
                            } else if (clazz == Short.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, 0);
                            } else if (clazz == Boolean.class) {
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, 0);
                            } else if (clazz ==List.class){
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, Lists.newArrayList());
                            }
                            else {
                                //3-6 未知类型直接赋值
                                org.springframework.data.util.ReflectionUtils.setField(m.getValue(), o, o);
                            }
                        }
                    }
                } catch (Exception e) {
                    writeLog("RetrunJsonAspect.after", Constant.LOG_ERROR, "返回值转换数据异常:" + o.toString());
                    throw new BusinessException("数据转换异常:" + e.getMessage());
                }
            });
        }
        Object result = point.getTarget();
        return result;
    }

    public Map<String,Field > objMap(Object obj) {
        Map<String,Field> map = new HashMap<String,Field>(16);
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            ReflectionUtils.makeAccessible(field);
            try {
                map.put(field.getName(), field);
            } catch (Exception e) {
                writeLog("ReturnJsonDiversion.ObjMap", Constant.LOG_ERROR, "字段取值异常:" + field.getName());
                throw new BusinessException("字段取值异常");
            }
        }
        return map;
    }
}
  @PostMapping("/find")
    @ReturnJsonDiversion
    public ReturnResult find(@RequestBody Input input) {
        ReturnResult output=xxService.find();
        return output;
    }

 

对aop概念和用法不理解的

传送门:

https://segmentfault.com/a/1190000007469968

https://segmentfault.com/a/1190000007469982

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值