介绍
1.PropertyPreFilter:根据PropertyName判断是否序列化–针对单个属性
2.PropertyFilter:根据PropertyName和PropertyValue来判断是否序列化–针对单条记录
3.NameFilter:修改Key值,如果需要修改Key,在process方法里面返回值即可
4.ValueFilter:修改Value值,如果需要修改Value,在process方法里面返回值即可
5.BeforeFilter:序列化时在最前面添加内容
6.AfterFilter:序列化时在最后面添加内容
PropertyPreFilter
作用
根据PropertyName判断是否序列化–针对单个属性
SimplePropertyPreFilter是PropertyPreFilter的普通子类,一般直接使用SimplePropertyPreFilter即可
可重写SimplePropertyPreFilter的process自定义序列化,也可以通过它的getExcludes()方法排除属性序列化、getIncludes()指定属性序列化
具体使用
/*** PropertyPreFilter* 根据PropertyName判断是否序列化--单个属性*/@GetMapping("propertyPreFilter")@ApiOperation(value ="测试PropertyPreFilter")public Result propertyPreFilter(){//创建对象SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(BigDecimal.TEN);serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);//序列化SimplePropertyPreFilter filter=new SimplePropertyPreFilter(){/**** @param writer* @param source 属性对象* @param name 属性名称* @return*/@Overridepublic boolean process(JSONWriter writer, Object source, String name) {return super.process(writer, source, name);}};//排除sex属性filter.getExcludes().add("sex");return new Result().ok(JSON.toJSONString(serializeDto,filter));}
输出结果
{"code": 0,"data": "{\"age\":20,\"money\":10,\"name\":\"测试\"}","msg": "success"
}
PropertyFilter
作用
根据PropertyName和PropertyValue来判断是否序列化–针对单条记录
可以通过重写PropertyFilter的apply()方法自定义序列化
具体使用
/*** PropertyFilter* 根据PropertyName和PropertyValue来判断是否序列化--行记录*/@GetMapping("propertyFilter")@ApiOperation(value ="测试propertyFilter")public Result propertyFilter(){//创建对象List<SerializeDto> list= Lists.newArrayList();SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(BigDecimal.TEN);serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);list.add(serializeDto);SerializeDto serializeDto1=new SerializeDto();serializeDto1.setMoney(BigDecimal.TEN);serializeDto1.setName("测试1");serializeDto1.setAge(30);serializeDto1.setSex(2);list.add(serializeDto1);//序列化,只输出年龄小于30return new Result().ok(JSON.toJSONString(list, new PropertyFilter() {/**** @param object 属性对象* @param name 属性名称* @param value 属性值* @return true 序列化 false 不序列化*/@Overridepublic boolean apply(Object object, String name, Object value) {if (object instanceof SerializeDto) {SerializeDto serializeDto = (SerializeDto) object;//只输出小于30if (serializeDto.getAge()!=null && serializeDto.getAge().intValue()<30) {return true;}}return false;}}));}
输出结果
{"code": 0,"data": "[{\"age\":20,\"money\":10,\"name\":\"测试\",\"sex\":1},{}]","msg": "success"
}
NameFilter
作用
修改Key值,如果需要修改Key,在process方法里面返回值即可
可以通过重写NameFilter的process方法自定义序列化
具体使用
/*** nameFilter* 修改Key,如果需要修改Key,process返回值则可* @return*/@GetMapping("nameFilter")@ApiOperation(value ="测试nameFilter")public Result nameFilter(){//创建对象SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(BigDecimal.TEN);serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);//序列化 属性名称统一大写return new Result().ok(JSON.toJSONString(serializeDto,new NameFilter(){/**** @param o 属性对象* @param s 属性名* @param value 属性值* @return*/@Overridepublic String process(Object o, String s, Object value) {//统一大写return s.toUpperCase();}}));}
输出结果
{"code": 0,"data": "{\"AGE\":20,\"MONEY\":10,\"NAME\":\"测试\",\"SEX\":1}","msg": "success"
}
ValueFilter
作用:
修改Value值,如果需要修改Value,在process方法里面返回值即可
可以通过重写NameFilter的process方法自定义序列化
具体使用
/*** valueFilter* 修改value值* @return*/@GetMapping("valueFilter")@ApiOperation(value ="测试valueFilter")public Result valueFilter(){//创建对象SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(new BigDecimal(2.355+""));serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);//序列化 对于BigDecimal类型的属性默认四舍五入保留两位小数return new Result().ok(JSON.toJSONString(serializeDto, new ValueFilter() {/*** 对于BigDecimal类型的属性默认四舍五入保留两位小数* @param o 属性对象* @param s 属性名* @param value 属性值* @return*/@Overridepublic Object process(Object o, String s, Object value) {if (value instanceof BigDecimal) {Field field = AnnotationUtilss.getFieldByName(o.getClass(), s);BigDecimalScale decimalScale = field.getAnnotation(BigDecimalScale.class);int newScale=2;RoundingMode roundingMode=RoundingMode.HALF_UP;if (decimalScale != null) {newScale=decimalScale.newScale();roundingMode= decimalScale.roundingMode();}BigDecimal bigDecimal = (BigDecimal) value;return bigDecimal.setScale(newScale,roundingMode).stripTrailingZeros();}return value;}}));}
输出结果
{"code": 0,"data": "{\"age\":20,\"money\":2.4,\"name\":\"测试\",\"sex\":1}","msg": "success"
}
BeforeFilter
作用
序列化时在最前面添加内容,可以通过BeforeFilter的writeBefore方法自定义序列化
具体使用
/*** beforeFilter* 序列化时在最前面添加内容* @return*/@GetMapping("beforeFilter")@ApiOperation(value ="测试beforeFilter")public Result beforeFilter(){//模拟字典值数据库Map<String,Map> map=Maps.newHashMap();Map<Object,String> sexMap = Maps.newHashMap();sexMap.put(1,"男");sexMap.put(2,"女");map.put("sex",sexMap);//创建对象SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(new BigDecimal(2.355+""));serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);//序列化 sex属性:1->男 2->女return new Result().ok(JSON.toJSONString(serializeDto,new BeforeFilter(){/*** @param object 属性对象*/@Overridepublic void writeBefore(Object object) {//获取该类的所有属性Field[] fields = AnnotationUtilss.getAllFields(object.getClass());for (Field field : fields) {//找到哪些属性上面还有dic注解Dic dic = field.getAnnotation(Dic.class);if (dic != null) {//将属性对象转成JSONObject,方便取属性值JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));//字典类型String key = dic.key();//新的属性名称String fieldName = dic.fieldName();//从字典里面取值,并创建新的属性if (!map.containsKey(key)) {writeKeyValue(fieldName,null);}else {Object value = jsonObject.get(field.getName());value=map.get(key).get(value);writeKeyValue(fieldName,value);}}}}}));}
输出结果
{"code": 0,"data": "{\"sexName\":\"男\",\"age\":20,\"money\":2.355,\"name\":\"测试\",\"sex\":1}","msg": "success"
}
AfterFilter
作用
序列化时在最后面添加内容可以通过AfterFilter的writeAfter方法自定义序列化
具体使用
/*** afterFilter* 序列化时在最后面添加内容* @return*/@GetMapping("afterFilter")@ApiOperation(value ="测试afterFilter")public Result afterFilter(){//模拟字典值数据库Map<String,Map> map=Maps.newHashMap();Map<Object,String> sexMap = Maps.newHashMap();sexMap.put(1,"男");sexMap.put(2,"女");map.put("sex",sexMap);List<SerializeDto> list=Lists.newArrayList();SerializeDto serializeDto=new SerializeDto();serializeDto.setMoney(new BigDecimal(2.355+""));serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(1);list.add(serializeDto);serializeDto=new SerializeDto();serializeDto.setMoney(new BigDecimal(2.355+""));serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(2);list.add(serializeDto);serializeDto=new SerializeDto();serializeDto.setMoney(new BigDecimal(2.355+""));serializeDto.setName("测试");serializeDto.setAge(20);serializeDto.setSex(3);list.add(serializeDto);return new Result().ok(JSON.toJSONString(list,new AfterFilter(){/*** @param object 属性对象*/@Overridepublic void writeAfter(Object object) {//获取该类的所有属性Field[] fields = AnnotationUtilss.getAllFields(object.getClass());for (Field field : fields) {//找到哪些属性上面还有dic注解Dic dic = field.getAnnotation(Dic.class);if (dic != null) {//将属性对象转成JSONObject,方便取属性值JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));//字典类型String key = dic.key();//新的属性名称String fieldName = dic.fieldName();//从字典里面取值,并创建新的属性if (!map.containsKey(key)) {writeKeyValue(fieldName,null);}else {Object value = jsonObject.get(field.getName());value=map.get(key).get(value);writeKeyValue(fieldName,value);}}}}}));}
输出结果
{"code": 0,"data": "[{\"age\":20,\"money\":2.355,\"name\":\"测试\",\"sex\":1,\"sexName\":\"男\"},{\"age\":20,\"money\":2.355,\"name\":\"测试\",\"sex\":2,\"sexName\":\"女\"},{\"age\":20,\"money\":2.355,\"name\":\"测试\",\"sex\":3,\"sexName\":null}]","msg": "success"
}
其他类
字典映射注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 字典值映射* @author leishen*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Dic {/*** 字典值类型* @return*/String key();/*** 新属性名称* @return*/String fieldName();
}
保留小数注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.RoundingMode;/*** @author leishen*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BigDecimalScale {/*** 保留位数* @return*/int newScale() default 2;/*** 舍入方式 默认四舍五入* @return*/RoundingMode roundingMode() default RoundingMode.HALF_UP;
}
实体类
mport com.zyp.annotation.BigDecimalScale;
import com.zyp.annotation.Dic;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** 测试fastJson定制序列化* @author leishen*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SerializeDto {@BigDecimalScale(newScale = 1)private BigDecimal money;/*** 性别*/@Dic(key = "sex",fieldName = "sexName")private Integer sex;/*** 姓名*/private String name;/*** 年龄*/private Integer age;
}
反射工具类
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class AnnotationUtilss {/*** 获取类和基类所有属性** @param clazz* @return*/public static Field[] getAllFields(Class<?> clazz) {List<Field> fieldList = new ArrayList<>();while (clazz != null) {fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));clazz = clazz.getSuperclass();}Field[] fields = new Field[fieldList.size()];return fieldList.toArray(fields);}/*** 获取指定属性** @param clazz* @param name* @return*/public static Field getFieldByName(Class<?> clazz, String name) {while (clazz != null) {try {return clazz.getDeclaredField(name);} catch (NoSuchFieldException e) {clazz = clazz.getSuperclass();}}return null;}
}
SpringBoot整合SerializeFilter序列化
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.zyp.config.serialize.DecimalValueFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {/*** 自定义消息转换器* @param converters initially an empty list of converters*/@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 清除默认 Json 转换器converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);// 配置 FastJsonFastJsonConfig config = new FastJsonConfig();config.setSerializerFeatures(SerializerFeature.QuoteFieldNames, SerializerFeature.WriteEnumUsingToString,SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat,SerializerFeature.DisableCircularReferenceDetect);//序列化配置SerializeConfig serializeConfig = SerializeConfig.globalInstance;//Long--->StringserializeConfig.put(Long.class , ToStringSerializer.instance);serializeConfig.put(Long.TYPE , ToStringSerializer.instance);config.setSerializeConfig(serializeConfig);config.setSerializeFilters(new DecimalValueFilter());// 添加 FastJsonHttpMessageConverterFastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();fastJsonHttpMessageConverter.setFastJsonConfig(config);List<MediaType> fastMediaTypes = new ArrayList<>();fastMediaTypes.add(MediaType.APPLICATION_JSON);fastMediaTypes.add(MediaType.APPLICATION_ATOM_XML);fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);fastMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);fastMediaTypes.add(MediaType.APPLICATION_PDF);fastMediaTypes.add(MediaType.APPLICATION_RSS_XML);fastMediaTypes.add(MediaType.APPLICATION_XHTML_XML);fastMediaTypes.add(MediaType.APPLICATION_XML);fastMediaTypes.add(MediaType.IMAGE_GIF);fastMediaTypes.add(MediaType.IMAGE_JPEG);fastMediaTypes.add(MediaType.IMAGE_PNG);fastMediaTypes.add(MediaType.TEXT_EVENT_STREAM);fastMediaTypes.add(MediaType.TEXT_HTML);fastMediaTypes.add(MediaType.TEXT_MARKDOWN);fastMediaTypes.add(MediaType.TEXT_PLAIN);fastMediaTypes.add(MediaType.TEXT_XML);fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);converters.add(fastJsonHttpMessageConverter);// 添加 StringHttpMessageConverter,解决中文乱码问题StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));converters.add(stringHttpMessageConverter);}
}