用AOP实现前端传参时间的时区转化
用AOP实现前端传参时间的时区转化
- 新增注解
- 新增AOP切面类
- Controller传参字段添加注解
- 结束
新增注解
@Documented
@Target({FIELD,METHOD,PARAMETER,ANNOTATION_TYPE})
@Retention(RUNTIME)
public @interface MyDateFormatDeserializer {String pattern() default "yyyy-MM-dd HH:mm:ss";String oldPattern() default "yyyy-MM-dd HH:mm:ss";
}
新增AOP切面类
@Aspect
@Component
public class MyDateFormatDeserializerAspect {private static Logger log = LoggerFactory.getLogger(MyDateFormatDeserializerAspect.class);@Pointcut("execution(* com.jovision.vse.*.*.web.controller..*.*(..))")public void pointCut() {}@Around("pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {//转换dateFormat(joinPoint);return joinPoint.proceed();}public void dateFormat(ProceedingJoinPoint joinPoint) {Object[] objects = null;try {objects = joinPoint.getArgs();if (objects.length != 0) {for (int i = 0; i < objects.length; i++) {//当前只支持判断对象类型参数convertObject(objects[i]);}}} catch (Exception e) {e.printStackTrace();throw new RuntimeException("参数异常");}}private void convertObject(Object obj) throws IllegalAccessException {if (Objects.isNull(obj)) {log.info("当前需要转换的object为null");return;}String timeZoneStr = CurrentUserUtil.currentTimeZone();if(StringUtils.isNotBlank(timeZoneStr)){List<Field> fieldList = getSuperFields(obj.getClass(),true);for (Field field : fieldList) {boolean containFormatField = field.isAnnotationPresent(MyDateFormatDeserializer.class);if (containFormatField) {//获取访问权field.setAccessible(true);MyDateFormatDeserializer annotation = field.getAnnotation(MyDateFormatDeserializer.class);String oldPattern = annotation.oldPattern();String newPattern = annotation.pattern();Object dateValue = field.get(obj);if (Objects.nonNull(dateValue) && !StringUtils.isEmpty(oldPattern) && !StringUtils.isEmpty(newPattern)) {String newValue = StringUtils.EMPTY;try {Date date = new Date();if(dateValue instanceof Date){date = (Date) dateValue;}else if(dateValue instanceof String){date = DateUtils.parseDate(dateValue.toString(), oldPattern);}else{log.error("parse date error,@MyDateFormatDeserializer must String or Date !!!");return;}SimpleDateFormat currentTime = new SimpleDateFormat(newPattern);TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);currentTime.setTimeZone(timeZone);newValue = currentTime.format(date);} catch (ParseException e) {throw new RuntimeException(e);}log.info("aop transform success - oldValue = {}, newValue = {} ",dateValue , newValue);field.set(obj, newValue);}}}}}/*** 获取类的所有属性(含所有父级类)* @param clazz* @param containSuperClass* @return*/private List<Field> getSuperFields(Class<?> clazz, boolean containSuperClass) {List<Field> fieldList = new ArrayList<>();//取父类属性while (clazz != null) {fieldList.addAll(Arrays.asList(clazz.getDeclaredFields())); //添加当前类全部属性if(containSuperClass){// 父类clazz = clazz.getSuperclass();}else{clazz = null;}}return fieldList;}
}
Controller传参字段添加注解
@Data
public class TestDto {/*** 查询的开始时间*/@MyDateFormatDeserializerprivate String queryStartTime;/*** 查询的结束时间*/@MyDateFormatDeserializerprivate String queryEndTime;
}
结束
这样,前端请求进到Controller后,开始执行业务逻辑之前,会将指定字段转化完时区并参与执行业务逻辑。
相关文章:
用AOP实现前端传参时间的时区转化
用AOP实现前端传参时间的时区转化 新增注解新增AOP切面类Controller传参字段添加注解结束 新增注解 Documented Target({FIELD,METHOD,PARAMETER,ANNOTATION_TYPE}) Retention(RUNTIME) public interface MyDateFormatDeserializer {String pattern() default "yyyy-MM-d…...
mybatis There is no getter for property named ‘*‘ in ‘class java.lang.String
mybatis There is no getter for property named car_port_ids in class java.lang.String 出现这种错误我这边是mapper.xml子查询字段不对导致的 我把查询结果的列的字段放进去结果不识别car_port_ids可能我这种字段本身就有问题 技术博客 http://idea.coderyj.com/ 1.解决 &…...
Mac终端前总会出现 (base) 字样解决
Mac安装了anaconda之后,终端前总会出现 (base) 字样,显示如下: (base) tinghoudeiMac ~ 具体原因是 安装了anaconda后,每次启动终端都会启动anaconda的base环境。 解决办法 设置anaconda 不自启base环境就好了: 禁用…...
RabbitMQ面试题大全含答案
rabbitmq 的使用场景有哪些? ①. 跨系统的异步通信,所有需要异步交互的地方都可以使用消息队列。就像我们除了打电话(同步)以外,还需要发短信,发电子邮件(异步)的通讯方式。 ②. 多…...

Linux配置QT Creator环境:ubuntu中安装QT Creator环境
一、前景 目前市面上很多公司使用QT Creator进行界面开发,基本都会选择在Linux环境进行,优点不仅是市场所需,更是方便后期代码的移植,相较于Windows系统,Linux系统移植性非常好。故此篇文章,介绍如何在Linu…...

机器学习深度学习——池化层
👨🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——卷积的多输入多输出通道 📚订阅专栏:机器学习&&深度学习 希望文章对你们…...

siMLPe:Human Motion Prediction
Back to MLP: A Simple Baseline for Human Motion Prediction解析 摘要1. 简介2. Related Work2.1 基于RNN的人体运动预测2.2 基于GCN的人体运动预测2.3 基于 Attention 的人类运动预测2.4 总结 3. siMLPe3.1 离散余弦变换(Discrete Cosine Transform (DCT)&#x…...
详解——JS map()方法
JavaScript是一种广泛使用的编程语言,用于开发Web应用程序。它具有许多内置函数和方法,其中之一是map()方法。map()方法是一个非常有用的函数,它允许我们在数组中的每个元素上执行相同的操作,并返回一个新的数组。 map()方法的语…...
leetcode做题笔记57
给你一个 无重叠的 ,按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 思路一:模拟题意 int pushbackInterval(int…...

SAP Fiori 将GUI中的自开发报表添加到Fiori 工作台
1. 首先我们在workbench 中开发一个GUI report 这里我们开发的是一个简单的物料清单报表 2. 分配一个事务代码。 注意这里的SAP GUI for HTML 要打上勾 3. 创建语义对象( Create Semantic Object) 事物代码: path: SAP NetWeaver ->…...
【Docker】配置指定大小的磁盘空间
背景 测试磁盘满时程序的运行情况 问题 如何使用 docker 来模拟磁盘满的情况 解决方法 创建指定大小的数据卷 volumedocker volume create --driver local --opt typetmpfs --opt devicetmpfs --opt osize50M my_volumn创建 docker 时,使用该数据卷docker run …...

使用Spring五大注解来更加简单的存储Bean对象
在使用Spring框架的时候我们如果使用这种方式来存储bean对象的话未免有点太麻烦了 <bean id"xxx" class"xxx"> </bean> 为了简化存储Bean对象的操作,我们可以使用五大类注解来进行存储Bean对象 我们首先要在配置文件配置扫描路径…...

Netty面试题1
计算机网络模型 OSI采用了分层的结构化技术,共分七层, 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 。 Open System Interconnect 简称OSI,是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参…...

水质分析积分球定义和原理
随着社会经济的快速发展,人们对水质的要求不断提升,特别是生活饮用水,检测项目渐趋完善。在工业化大发展的前提下,水资源正遭受着严重的污染,因此确保水质安全,定期开展对饮用水的检测工作已迫在眉睫。环境…...
自然语言处理从入门到应用——LangChain:记忆(Memory)-[基础知识]
分类目录:《自然语言处理从入门到应用》总目录 默认情况下,链(Chains)和代理(Agents)是无状态的,这意味着它们将每个传入的查询视为独立的(底层的LLM和聊天模型也是如此)…...

phpstorm添加vue 标签属性绑定提示和提示vue的方法提示
v-text v-html v-once v-if v-show v-else v-for v-on v-bind v-model v-ref v-el v-pre v-cloak v-on:click v-on:keyup.enter v-on:keyup click change input number debounce transition :is :class把上面这些文字粘贴到点击右下角放大按钮 后的文本框里,然后保存…...
从计算到人类知识:ChatGPT与智能演化
引 言 智能是自然界演化出来的结果,而人工智能则是人类创造的产物。随着人工智能的不断进步,尤其是近期ChatGPT的开放,我们发现人工智能的智能水平似乎已经达到了非常高的水平。然而,对于自然界中生物来说很简单的行为࿰…...

Leetcode每日一题:2681. 英雄的力量(2023.8.1 C++)
目录 2681. 英雄的力量 题目描述: 实现代码与解析: 数学规律 原理思路: 2681. 英雄的力量 题目描述: 给你一个下标从 0 开始的整数数组 nums ,它表示英雄的能力值。如果我们选出一部分英雄,这组英雄的…...
【学习】若依源码(前后端分离版)之 “ 异常处理”
大型纪录片:学习若依源码(前后端分离版)之 “ 异常处理” 前言1、统一返回实体定义2、定义登录异常定义3、基于ControllerAdvice注解的Controller层的全局异常统一处理4、测试访问请求结语 前言 通常一个web框架中,有大量需要处理…...

天花板级,Python接口自动化测试-接口关联封装调用(实例)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 流程相关的接口&a…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...