用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…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
