摘要
本文中写的注解的作用是再Controller中返回体中,如果某个属性为空,则返回指定的一个默认值。
本文中写的注解的作用是再Controller中返回体中,如果某个属性为空,则返回指定的一个默认值。
fastJson提供了很多不错的注解,例如@JsonProperty,@JsonFormat等,但是还是没找到我想要的如果属性为空,则返回一个指定的默认值的注解,于是就自己在Spring Boot项目中模拟fastJson实现了这个注解。
这个注解的作用如下:当Controller中的responseBody中的属性为空null(你也可以自己定义规则),则返回注解中指定的默认值,示例如下:
@JsonDefaultValue(defaultVal = "---") private Integer age;
上面示例的作用就是,当age为null时,将会返回前端---
首先我们要定义一个注解,这个注解就是上面属性中的注解
package com.example.demo.aop; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface JsonDefaultValue { String defaultVal(); }
其次,我们要写一个判断默认值赋值的逻辑实现类
package com.example.demo.aop; import java.lang.reflect.Field; import java.util.Date; import com.alibaba.fastjson.serializer.ValueFilter; import lombok.extern.slf4j.Slf4j; /** * 在fastjson中使用此过滤器进行脱敏操作 */ @Slf4j public class ValueDefaultFilter implements ValueFilter { @Override public Object process(Object object, String name, Object value) { JsonDefaultValue desensitization; Field field = null; try { field = object.getClass().getDeclaredField(name); if ((desensitization = field.getAnnotation(JsonDefaultValue.class)) == null) { return value; } } catch (NoSuchFieldException e) { log.error("当前数据类型为{},值为{}", object.getClass(), value); return value; } String defalueVal = desensitization.defaultVal(); if (value == null) { return defalueVal; } if (String.class == field.getType()) { return value.toString(); } if (Boolean.class == field.getType()) { return (boolean) value; } if (Integer.class == field.getType()) { return (int) value; } if (Double.class == field.getType()) { return (double) value; } if (Date.class == field.getType()) { return (Date) value; } log.error("当前数据类型为{},没有对应的处理逻辑,返回值为{}", object.getClass(), value); return value; } }
需要注意的是:这个处理逻辑目前仅仅支持Integer、String、Boolean、Double、Date包装类,如果您想添加新的类型支持,请自己添加对应的逻辑即可。
最后,我们需要将此拦截器加入到Spring容器中
package com.example.demo.aop; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @Slf4j public class WebConfigurer implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { } /** * 配置fastjson为默认JSON转换 * * @return */ @Bean public HttpMessageConverters fastJsonHttpMessageConverters() { log.info("启用自定义注解!!!"); // 1.定义一个converters转换消息的对象 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter(); // 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json数据 FastJsonConfig fastJsonConfig = new FastJsonConfig(); fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat); fastJsonConfig.setSerializeFilters(new ValueDefaultFilter());//添加自己写的拦截器 // 3.在converter中添加配置信息 fastConverter.setFastJsonConfig(fastJsonConfig); // 4.将converter赋值给HttpMessageConverter HttpMessageConverter<?> converter = fastConverter; // 5.返回HttpMessageConverters对象 return new HttpMessageConverters(converter); } }
测试实体类如下:
package com.example.demo.entity; import java.util.Date; import com.example.demo.aop.JsonDefaultValue; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data public class TestResponse { @JsonDefaultValue(defaultVal = "---") private String name; @JsonDefaultValue(defaultVal = "---") private String addr; @JsonDefaultValue(defaultVal = "---") private Integer age; @JsonDefaultValue(defaultVal = "---") private Boolean isMen; @JsonDefaultValue(defaultVal = "---") private Date currentDate; }
Controller如下:
package com.example.demo.controller; import java.util.Date; import com.example.demo.entity.TestResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping(value = "/test") public class TestJsonDefaultController { @RequestMapping(value = "/getDealerLicense") @ResponseBody public TestResponse getDealerLicense(String name) { TestResponse testResponse = new TestResponse(); testResponse.setAddr(null); testResponse.setAge(12); testResponse.setIsMen(null); testResponse.setName(name); testResponse.setCurrentDate(new Date()); return testResponse; } }
访问测试结果如下:
{ "addr": "---", "age": 12, "currentDate": 1627981079705, "isMen": "---", "name": "李四"