操作日志需要记录修改前修改后的信息对比

这是一个java对象比较的方法。可以返回一句话,修改了对象的哪个字段,修改前是什么,修改后是什么


import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;/*** 对象比较并得出比较结果的方法*/
public class ObjectCompareUtils {private static Logger logger = LoggerFactory.getLogger(ObjectCompareUtils.class);private static Set<String> ignores = new TreeSet<>();static {ignores.add("serialVersionUID");ignores.add("id");ignores.add("creator");ignores.add("createTime");ignores.add("modifier");ignores.add("modifyTime");}static class MyAttr {String attrName;String attrValue;String attrDesc;}private static Map<String, MyAttr> parseObj(Object obj) {Map<String, MyAttr> rsMap = new HashMap<>();//得到classClass cls = obj.getClass();//得到所有属性Field[] fields = cls.getDeclaredFields();for (int i=0;i<fields.length;i++){try {//得到属性Field field = fields[i];//打开私有访问field.setAccessible(true);//获取属性String name = field.getName();if (ignores.contains(name)) {continue;}logger.info("字段 -- {}", name);//获取属性值Object value = field.get(obj);Annotation[] an = field.getDeclaredAnnotations();ApiModelProperty myFieldAnnotation = field.getAnnotation(ApiModelProperty.class);MyAttr myAttr = new MyAttr();myAttr.attrName = name;myAttr.attrValue = (value == null ? "" : value.toString());if (myFieldAnnotation != null) {myAttr.attrDesc = myFieldAnnotation.value();}rsMap.put(name, myAttr);} catch (IllegalAccessException e) {e.printStackTrace();}}return rsMap;}/*** 比较2个对象,需要对象的所属类标记了swagger的属性注解《ApiModelProperty》* @param newObj 新对象* @param oldObj 旧对象* @param style 比较结果的样式* @return*/public static String compareObj(Object newObj, Object oldObj, RESULT_STYLE style) {Map<String, MyAttr> newAttrMap =  parseObj(newObj);Map<String, MyAttr> oldAttrMap =  parseObj(oldObj);Iterator<Map.Entry<String, MyAttr>> newIt = newAttrMap.entrySet().iterator();String oldValue = "";String newValue = "";StringBuilder sb = new StringBuilder();while (newIt.hasNext()) {Map.Entry<String, MyAttr> entry = newIt.next();newValue = entry.getValue().attrValue;oldValue =  oldAttrMap.get(entry.getKey()).attrValue;if (!newValue.equals(oldValue)) {sb.append(renderResutl(entry.getValue().attrDesc, oldValue, newValue, style));}}return sb.toString();}/*** 返回结果渲染* @param desc* @param oldValue* @param newValue* @param style* @return*/private static String renderResutl(String desc, String oldValue, String newValue, RESULT_STYLE style) {if (style == RESULT_STYLE.NONE) {return "将 " + desc + " 从 " + oldValue+ " 修改为 " + newValue;} else if (style == RESULT_STYLE.RED_BLUE){return "将 <font color=\"#50A6FF\">" + desc + "</font> 从 <font color=\"#FF9900\">" + oldValue+ "</font> 修改为 <font color=\"#FF9900\">" + newValue + "</font><br/>";} else {return "将 \"" + desc + "\" 从 \"" + oldValue+ "\" 修改为 \">" + newValue + "\"<br/>";}}/*** 比对结果样式枚举*/public enum RESULT_STYLE {/*** 无样式*/NONE(0,"无样式"),/*** 红蓝色样式*/RED_BLUE(1,"红蓝色样式"),/*** 双引号样式*/DOUBLE_QUOTES(2,"双引号样式");RESULT_STYLE(Integer key, String value) {this.key = key;this.value = value;}private Integer key;private String value;public Integer getKey() {return key;}public void setKey(Integer key) {this.key = key;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}}public static void main(String[] args) {CompanyUpdateVo update = new CompanyUpdateVo();update.setCompanyName("新公司");update.setCompanyCode("10002");CompanyEntity old = new CompanyEntity();old.setCompanyName("旧公司");String text = ObjectCompareUtils.compareObj(update, old, RESULT_STYLE.RED_BLUE);System.out.println(text);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

第18篇 :深入剖析systemverilog中 randomize 失败案例启示录(二)

今天我们继续修改之前的例子&#xff0c;你会有意想不到的收获。程序源代码&#xff0c;和上一节文章一样。 症状3&#xff1a; 这里&#xff0c;我们没有显式调用类的randomize() 函数&#xff0c;而是定义了一个类函数。在函数中 &#xff0c;重新约束了类内的随机变量。请…

CC音乐 1.0 | 纯净版音乐软件,内置3条音源,支持无损和母带下载

CC音乐是一款全新上架的第三方音乐软件&#xff0c;界面纯净简洁且无广告。内置三条音源接口&#xff0c;用户可以畅听全网音乐。软件涵盖了电台、排行榜、歌单分类、视频、歌手等多个栏目&#xff0c;即使是会员和灰色歌曲也能随意畅听。此外&#xff0c;CC音乐还支持下载无损…

【销帮帮-注册_登录安全分析报告-试用页面存在安全隐患】

联通支付注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨…

windows中docker安装redis和redisinsight记录

创建一个Redis运行容器&#xff0c;命令如下 docker run -it -d --name redis -p 6379:6379 redis --bind 0.0.0.0 --protected-mode no -d 代表Redis容器后台运行 --name redis 给创建好的容器起名叫redis -p 6379:6379 将容器的6379端口映射到宿主机的6379端口&#xff0c;注…

问题排查:C++ exception with description “getrandom“ thrown in the test body

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 MotivationProcess Motivation 最近在做一个复杂系统集成到 Bazel 的工作。 在编译…

C++中类的默认成员函数

默认成员函数 1.构造函数2.析构函数3.拷贝构造函数4.赋值运算符重载4.1运算符重载4.2赋值运算符重载 #mermaid-svg-oipiwg9stvONvYK0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-oipiwg9stvONvYK0 .error-icon{f…

从0开始学习机器学习--Day20--优化算法的思路

确定执行的优先级(Prioritizing what to work on : Spam classification example) 在建立学习系统前&#xff0c;我们不仅要梳理框架&#xff0c;更重要的是我们要弄清楚有哪些事情是要优先做的&#xff0c;这可以帮我们节约大量的时间。 以垃圾邮件为例&#xff0c;按照之前…

利用JS实现图片轮播(示例)

我们平时在逛购物网站的时候会看到页面内的商品图片自动轮播&#xff0c;二要想实现着中效果应该如何做呢&#xff1f;下面详细讲解代码的运用&#xff0c;实现下面视频的效果。大家也可以自己试试看&#xff0c;或者复制最后的完整代码运行一下&#xff01; 图片自动轮播效果 …

关于99.9% 达成读码率方案

1.标签样式 2.尺寸大小 长30mm*宽30mm 至 长40mm*宽40mm ; 3.位置 标签位置在箱体中间,可以误差5mm; 4.质量要求 ①无遮挡,标签不允许任何介质在上面,尤其是塑料片 ②平整,必须和箱子壁贴平,不允许翻边,飘荡。 ③码不能有模糊,手机摄像头扫码可以…

w~视觉~合集20~SAM

我自己的原文哦~ https://blog.51cto.com/whaosoft/12500982 #SAM 今天&#xff0c;Meta发布史上首个图像分割基础模型SAM&#xff0c;将NLP领域的prompt范式引进CV&#xff0c;让模型可以通过prompt一键抠图。网友直呼&#xff1a;CV不存在了! 就在刚刚&#xff0c;Meta AI…

三、直流有刷电机H桥驱动原理

1、H桥简介 H桥驱动电路&#xff1a;是一种用于控制直流电机正反转及速度的电路&#xff0c;其名称来源于其电路结构类似于字母“H”。H桥驱动电路由四个开关元件&#xff08;如晶体管、MOSFET等&#xff09;组成&#xff0c;这些开关元件被配置成可以控制电机两端电流的方向&…

Leetcode刷题

题目如下&#xff1a; 这道题呢&#xff0c;这里我写出了两种解决办法&#xff0c;一种遍历链表来得出中间结点&#xff0c;一种通过快慢指针来得出中间结点 第一种&#xff1a; 遍历&#xff1a; 首先我们设置一个计数器count&#xff0c;来记录链表的长度&#xff0c;写一…

游戏开发--C#面试题

游戏开发--C#面试题 C#1. 值类型和引用类型的区别2. 重载和重写的区别3. ArrayList和List的区别4. List底层是什么实现的&#xff1f;5. 抽象类和接口的区别6. 静态成员和⾮静态成员的区别7. 装箱和拆箱是指什么&#xff1f;8. 值和引用类型在变量赋值时的区别是什么&#xff1…

# 设置ubuntu为中文后,如何保留用户家目录等文件夹名为英文

设置ubuntu为中文后&#xff0c;如何保留用户家目录等文件夹名为英文 一、问题描述&#xff1a; 当我们安装完ubuntu系统后&#xff0c;通过【系统设置】&#xff0c;在【语言支持】里&#xff0c;设置为【汉语&#xff08;中国&#xff09;】&#xff0c;这时在终端中显示文…

STM32—独立看门狗(IWDG)和窗口看门狗(WWDG)

概述&#xff1a; WDG(Watchdog) 看门狗&#xff0c;看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能计时复位程序&#xff0c;避免程序陷入长时间的罢工状态&#xff0c;保证系…

Chrome与火狐哪个浏览器的性能表现更好

在数字时代&#xff0c;浏览器是我们日常生活中不可或缺的工具。无论是工作、学习还是娱乐&#xff0c;一个好的浏览器都能显著提高我们的效率和体验。市场上有许多优秀的浏览器&#xff0c;其中Google Chrome和Mozilla Firefox无疑是最受欢迎的两款。本文将比较这两款浏览器的…

现在国内优秀的广告联盟有哪些?

广告联盟是网络广告效果营销的主流方式之一&#xff0c;广告联盟的变现方式多种多样&#xff0c;主要有以下四种 CPA&#xff1a;按照下载或者注册进行付费&#xff08;软件平台或游戏试玩平台&#xff09;CPS&#xff1a;按照成交进行付费&#xff08;淘宝客&#xff09;CPM&…

机器学习,生成式AI ,LLM大模型,人工智能,他们之间的关系是什么?有什么不同?

这些概念都是现代计算机科学和人工智能领域的重要组成部分&#xff0c;它们之间既有联系&#xff0c;也有区别。以下是它们的关系和不同之处&#xff1a; 人工智能 (AI) 两个回答 人工智能是一个广义的概念&#xff0c;指的是计算机系统能够执行通常需要人类智能才能完成的任务…

[全网最细数据结构完整版]第七篇:3分钟带你吃透队列

目录 1->队列的概念及结构 2->队列的实现 2.1定义队列基本结构 struct QueueNode 和 struct Queue 2.2队列初始化函数 QueueInit 函数 2.3队列销毁函数 QueueDestroy 函数 2.4队列插入数据函数 QueuePush 函数 2.5判断队列是否为空,空返回true,非空返回false 2.6队列删…

点阵数显驱动IC数显LED驱动芯片VK1651

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1651 封装形式&#xff1a;SOP16 产品年份&#xff1a;新年份 产品简介&#xff1a;VK1651是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动、键盘扫描等电路。SEG脚…