SpringBoot整合SerializeFilter序列化

news/2024/4/18 16:20:16/文章来源:https://blog.csdn.net/m0_46360888/article/details/129262147

介绍

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);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75624.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SkyWalking简介和安装

APM系统 早期的监控系统功能比较单一&#xff0c;主要以监控CPU、内存、网络、I/O等基础设置为主&#xff08;cacti、nagios&#xff09; 后来随着中间件技术的不断发展&#xff0c;监控系统也开始监控缓存、数据库、MQ等各种基础组件的性能&#xff08;zabbix、prommethus&a…

【MinIO】文件断点续传和分块合并

【MinIO】文件断点续传和分块合并 文章目录【MinIO】文件断点续传和分块合并0. 准备工作1. 检查文件是否存在1.1 定义接口1.2 编写实现方法2. 检查分块文件是否存在2.1 定义接口2.2 编写实现方法3. 上传分块文件接口3.1 定义接口3.2 编写实现方法4. 合并分块文件接口4.1 定义接…

Python - Opencv应用实例之CT图像检测边缘和内部缺陷

Python - Opencv应用实例之CT图像检测边缘和内部缺陷 将传统图像处理处理算法应用于CT图像的边缘检测和缺陷检测,想要实现效果如下: 关于图像处理算法,主要涉及的有:灰度、阈值化、边缘或角点等特征提取、灰度相似度变换,主要偏向于一些2D的几何变换、涉及图像矩阵的一些统…

java中使用protobuf总结

基本没怎么接触过java编程&#xff0c;别的团队发过来一个用java编写的存储pb的文件&#xff0c;让拆分和解析&#xff0c;硬着头皮做一下&#xff0c;在此将步骤做个记录&#xff1a;下载安装protobufhttps://github.com/protocolbuffers/protobuf/tags?afterv3.6.1.2编译pro…

AI/CV大厂笔试LeetCode高频考题之基础核心知识点

AI/CV互联网大厂笔试LeetCode高频考题之基础核心知识点算法复习1、二叉树的遍历2、回溯算法3、二分搜索4、滑动窗口算法题5、经典动态规划6、动态规划答疑篇6.1、总结一下如何找到动态规划的状态转移关系7、编辑距离8、戳气球问题9、最长公共子序列 Longest Common Subsequence…

系统性能测试指标

性能测试的目的 1.评估系统的能力&#xff0c;测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力&#xff0c;并帮助作出决策。 2.识别体系中的弱点&#xff1a;受控的负荷可以被增加到一个极端的水平&#xff0c;并突破它&#xff0c;从而修复体系的瓶颈或薄…

兴达易控Modbus转Profinet网关将丹佛斯变频器接入西门子1200PLC配置案例

案例简介&#xff1a; 本案例是兴达易控Modbus转Profinet网关连接丹佛斯变频器在西门子1200PLC程序控制实例&#xff0c;实现对变频器频率读写&#xff0c;及工作模式切换。 用到的设备为西门子1200PLC一台&#xff0c;丹佛斯变频器一台,兴达易控Modbus转Profinet网关一个 Modb…

OSPF -- (开放式最短路径优先协议)(公共协议)

OSPF -- &#xff08;开放式最短路径优先协议&#xff09;&#xff08;公共协议&#xff09; 1、属性&#xff1a;无类别链路状态IGP协议 无类别&#xff1a;更新携带精确掩码 链路状态&#xff1a;共享拓扑&#xff08;共享LSA&#xff09;本地计算路由IGP&#xff1a; 基于…

读取/etc/profile时发现错误:

读取/etc/profile时发现错误&#xff1a; /etc/profile:行XX&#xff1a;***************** /etc/profile:行XX&#xff1a;***************** 今天遇到这个错误&#xff0c;发现是首行被我编辑时删错了一个符号导致报错&#xff0c;导致每次开机都会报这个文件错误&#xff0…

SpringBoot解决跨域方式

跨域是指在 Web 应用中&#xff0c;一个服务器资源或应用访问另一个服务器资源或应用的资源时候。由于浏览器的同源策略&#xff0c;一般情况下同一个域中的网站或应用可以互相访问资源&#xff0c;但跨域访问会被浏览器拒绝。浏览器出于安全考虑&#xff0c;会限制跨域访问&am…

Jmeter性能测试 入门

Jmeter是一款优秀的开源测试工具&#xff0c; 是每个资深测试工程师&#xff0c;必须掌握的测试工具&#xff0c;熟练使用Jmeter能大大提高工作效率。 熟练使用Jmeter后&#xff0c; 能用Jmeter搞定的事情&#xff0c;你就不会使用LoadRunner了。 我将会覆盖Jmeter的各个功能…

亿发软件:钉钉移动ERP业务在线,审批、管理更方便!

钉钉系统是企业级智能移动办公平台&#xff0c;平台覆盖大中小微各量级企业&#xff0c;帮助中国企业移动办公管理。企业无需复杂的部署操作&#xff0c;在对应的功能制定流程和相关负责人即可。 亿发企业ERP管理系统于2022年与钉钉系统做了对接&#xff0c;提供一站式的企业管…

大数据系统重点

第一章 大数据计算系统概述 1 大数据计算框架概述 计算框架: 一种抽象&#xff0c;在其中提供相应的通用功能供用户编写代码以实现具体功能&#xff0c;从而形成面向应用的软件。 大数据计算框架&#xff1a;面向大数据的计算框架。 Hadoop Hadoop的运行过程 Hadoop的详细…

腾讯云轻量应用服务器和云服务器CVM有什么区别?

腾讯云新推出的轻量应用服务器Lighthouse和原来的CVM云服务器有什么区别&#xff1f;轻量应用服务器Lighthouse是一种易于使用和管理、适合承载轻量级业务负载的云服务器&#xff0c;主要用于Web网站应用&#xff0c;轻量服务器使用及后期运维更加简单方便&#xff1b;云服务器…

【数据结构(四)】树

文章目录树1 树的基本概念1.1 树的定义1.2 基本术语1.3 数的性质2 二叉树的概念2.1 二叉树的定义与特性2.1.1 定义2.1.2 二叉树的性质2.2 几种特殊的二叉树2.2.1 满二叉树2.2.2 完全二叉树2.3 二叉树的存储结构2.3.1 顺序存储2.3.2 链式存储3 二叉树的遍历和线索二叉树3.1 二叉…

敏捷-期末

什么是敏捷开发&#xff1f; 敏捷开发(Agile Development)是一种以人为核心、迭代、循序渐进的开发方法。 怎么理解呢&#xff1f;它不是一门技术&#xff0c;它是一种开发方法&#xff0c;也就是一种软件开发的流程&#xff0c;它会指导我们用规定的环节去一步一步完成项目的开…

二叉树路径查找

题目描述&#xff1a;给定一棵二叉树(结构如下)&#xff0c;其中每个节点值为整数。给定一个值 K&#xff0c;求所有满足如下条件的路径并将路径上节点的值打印出来&#xff1a; 1、路径方向必须向下&#xff0c;即只能从父节点指向子节点 2、路径并不是必须从根节点开始或在叶…

一起玩转开源数据库!OceanBase DevCon 之开源生态全景解析

​ 2023 年 3 月 25 日&#xff0c;首次 OceanBase 开发者大会将在北京举办&#xff0c;OceanBase 首席科学家阳振坤与 OceanBase CTO 杨传辉领携众多技术专家&#xff0c;将与开发者共同探讨单机分布式、云原生、HTAP 等数据库前沿趋势&#xff0c;OceanBase 开源技术全景生…

【安卓】安卓设备实现wifi display解决方案

看文章前&#xff0c;我们需要知道的几个概念&#xff1a; 1、Wifi Direct技术&#xff1b; 2、Wifi Display技术&#xff1b; 3、Miracast标准&#xff1b; 安卓手机用户都知道我们的安卓手机有一个wifi直连功能&#xff0c;在点击设置–》WIFI–》更多Wifi设置–》Wifi直连&a…

【Linux】操作系统与Linux — Linux概述、组成及目录结构

目录 一、什么是操作系统&#xff1f;都有那些&#xff1f; 二、Linux概述 三、Linux组成 三、Linux目录结构 四、Linux目录结构 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一下 一、什么是操作系统&#xff1f;都有那些&#x…