用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…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...