苍穹外卖(四) AOP切面公共字段自动填充及文件上传

news2024/11/25 20:41:35

一.AOP切面公共字段填充

问题分析

如果都按照上述的操作方式来处理这些公共字段, 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐,那能不能对于这些公共字段在某个地方统一处理,来简化开发呢?

答案是可以的,我们使用AOP切面编程,实现功能增强,来完成公共字段自动填充功能。

 实现思路

1. 2 在发生insert操作时 需要为字段赋值

3. 4 在发生insert update操作时 需要为字段赋值

我们为了简便操作就要通过切面这种方式统一处理为这几个字段赋值的操作

比如在持久层Mapper 执行insert, 就可以通过切面拦截这个insert操作

我们还需要设置一个手段, 能够知道当前持久层的操作是否需要为公共字段赋值(一堆连接点怎么找切入点)

我们就是通过 自定义注解 的方式为这个Mapper的方法加入注解, (让这个方法成为切入点)

作为一个标识表示该操作需要赋值 没有标识就不需要

整体实现过程:

 技术点:枚举、注解、AOP、反射

1) 枚举(创建一个枚举类, 包含insert, update, 加在注解类AutoFill内部,用以区分是需要为四个字段还是两个字段赋值)

2). 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法

3). 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值

 在内部使用反射机制完成赋值

//根据当前不同的操作类型,为对应的属性通过反射来赋值
        if(operationType == OperationType.INSERT){
            //为4个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setCreateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if(operationType == OperationType.UPDATE){
            //为2个公共字段赋值
            try {
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

4). 在 Mapper 的方法上加入 AutoFill 注解

二. 阿里云文件上传 

因为在新增菜品时,需要上传菜品对应的图片(文件),包括后绪其它功能也会使用到文件上传,故要实现通用的文件上传接口。

文件上传,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发抖音、发朋友圈都用到了文件上传功能。

实现文件上传服务,需要有存储的支持,那么我们的解决方案将以下几种:

  1. 直接将图片保存到服务的硬盘(springmvc中的文件上传)
    1. 优点:开发便捷,成本低
    2. 缺点:扩容困难
  2. 使用分布式文件系统进行存储
    1. 优点:容易实现扩容
    2. 缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS,MinIO)
  3. 使用第三方的存储服务(例如OSS)
    1. 优点:开发简单,拥有强大功能,免维护
    2. 缺点:付费

在本项目选用阿里云的OSS服务进行文件存储。(前面课程已学习过阿里云OSS,不再赘述)

实现步骤:

 1). 定义OSS相关配置

 

2). 读取OSS配置

配置属性类  加载yml文件  完成赋值

3). 生成OSS工具类对象

项目启动时就可以加载下面这个配置类

启动程序 自动加载

其中AliOssUtil类

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

    private String endpoint;
    private String accessKeyId;
    private String accessKeySecret;
    private String bucketName;

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
           ///
        } catch (ClientException ce) {
            
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}

 4). 定义文件上传接口

@RestController
@RequestMapping("/admin/common")
public class CommonController {

    @Autowired
    private AliOssUtil aliOssUtil;

    /**
     * 文件上传
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file){
        log.info("文件上传:{}",file);

        try {
            //原始文件名
            String originalFilename = file.getOriginalFilename();
            //截取原始文件名的后缀   dfdfdf.png
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            //构造新文件名称
            String objectName = UUID.randomUUID().toString() + extension;

            //文件的请求路径
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            log.error("文件上传失败:{}", e);
        }

        return Result.error(MessageConstant.UPLOAD_FAILED);
    }
}

 

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

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

相关文章

Redis订阅和发布

Redis订阅和发布 一、订阅者和发布者二、使用示例三、常用命令 一、订阅者和发布者 发布者&#xff1a;publish&#xff0c;发送消息订阅者&#xff1a;subscribe&#xff0c;接收消息 如下图所示&#xff0c;可以有多个订阅者订阅同一个频道&#xff0c;如果该频道发送消息&…

【RocketMQ系列一】初识RocketMQ

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

thinkphp6入门(9)-- 获取url路径中的应用名、控制器名、操作名

如果使用了多应用模式&#xff0c;可以通过下面的方法来获取当前应用 app(http)->getName(); 获取当前控制器 Request::controller(); 获取当前操作 Request::action(); 在中间件middleware中是无法获取控制器和操作的 需要将middleware的引入修改为 config 目录下的 ro…

计算机网络 实验六 Wireshark 抓包实验

实验目的&#xff1a; 通过实验掌握下列知识&#xff1a; 1. 掌握Wireshark抓包工具的使用。 2. 掌握建立telnet用户密码登录方式&#xff0c;并通过wireshark抓取相关信息。 3. 理解TCP的包结构&#xff0c;并掌握TCP建立连接的过程。 4. 掌握使用tftp工具&#xff0c;上…

一文带你了解以色列的当红38家网络安全公司

2014年&#xff0c;以色列出口的网络安全产品总值达60亿美金&#xff0c;占领了全球10%的网络安全市场。2014-2016年&#xff0c;微软用3.2亿美元买下数据隐私公司Adallom&#xff1b;Facebook花了1.5亿美元收购移动端数据分析公司Onavo&#xff1b;PayPal以6千万美元收下CyAct…

2023面试知识点二

1、vue双向绑定是如何实现的 原理主要通过数据劫持和发布订阅模式实现的通过Object.defineProperty()来劫持各个属性的setter&#xff0c;getter&#xff0c;监听数据的变化在数据变动时发布消息给订阅者(watcher)&#xff0c;订阅者触发响应的回调(update)更新视图。 2、ing…

非一线工程管理者的一对一沟通

一线工程管理者主要管理/领导工程师完成实际的工程任务&#xff0c;而非一线的工程管理者需要领导一线管理者&#xff0c;更多的关注团队本身&#xff0c;因此两者在做一对一沟通的时候需要有不同的关注点。原文: One-on-Ones for (Engineering) Manager of Managers 如果没有耐…

Linux该如何学习,给你支招

如果你已经确定对 Linux 产生了兴趣&#xff0c;那么接下来我们介绍一下学习 Linux 的方法。这只是自己关于学习Linux的建议。 一、如何去学习 学习大多类似庖丁解牛&#xff0c;对事物的认识一般都是由浅入深、由表及里的过程&#xff0c;循序才能渐进。学习 Linux 同样要有一…

复旦MBA魏文童:构建完备管理知识体系,助力企业数字化发展

日月光华&#xff0c;旦复旦兮&#xff01;复旦MBA如同一个巨大的磁场&#xff0c;吸引了诸多来自五湖四海、各行各业的职场精英。从初入职场的青涩懵懂到如今的独当一面专业干练&#xff0c;他们逐渐成长为职场的中坚力量&#xff0c;在各自领域内发光发热。作为新时代的青年&…

怒刷LeetCode的第27天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;位运算 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;贪心算法 第三题 题目来源 题目内容 解决方法 方法一&#xff1a;二分查找 方法二&#xff1a;牛顿迭代法 方法三&#xff1a;位操作…

基于Pytest接口自动化的requests模块项目实战以及接口关联方法详解

1、基于pytest单元测试框架的规则 1.1 模块名&#xff08;即文件名&#xff09;必须以test_开头或者_test结尾 1.2 类名必须以Test开头且不能有init方法 1.3 用例名&#xff08;测试方法&#xff09;必须以test开头 同时&#xff0c;我也为大家准备了一份软件测试视频教程&…

【算法-动态规划】零钱兑换 II-力扣 518

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

Smartforms 打印出现的问题

上半年ECC做了升级 程序代码从ECC迁移到S4 有用户反馈 打印不能用了 经过调试发现在打印程序中 竟然返回2&#xff0c;但是 smartforms ZRPT_CO_YFLL_DY又是存在的 。 然后去激活 并与 ECC对比发现问题 S4的页大小竟然这么小 找到对应的页格式 对比ECC和S4 果然是这个…

2023年中国商用服务机器人行业发展概况分析:国产机器人厂商向海外进军[图]

商用服务机器人指在非制造业的商用服务场景中&#xff0c;用来替代或辅助人类进行服务性质工作的机器人&#xff1b;常见的商用场景中&#xff0c;商用服务机器人主要分为终端配送类机器人&#xff0c;商用清洁类机器人&#xff0c;引导讲解类机器人等&#xff0c;被广泛应用在…

7+线粒体相关基因预后模型+肿瘤微环境+免疫细胞浸润+实验验证

今天给同学们分享一篇线粒体预后模型实验的生信文章“Constructing a novel mitochondrial-related gene signature for evaluating the tumor immune microenvironment and predicting survival in stomach adenocarcinoma”&#xff0c;这篇文章于2023年3月13日发表在J Trans…

Spring Boot 生成二维码

效果图 1.maven依赖 <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId>

力扣 095. 最长公共子序列(C语言+动态规划)

1. 题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08…

强化学习

文章目录 强化学习概念Model-FreeValue-based learningDQN State-based learning蒙特卡洛近似 Actor-Critic LearningModel-BasedMonte Carlo TreeSearch(MCTS)-AlphaGo 强化学习概念 Terminologies&#xff08;术语&#xff09; State s&#xff1a;环境的一个状态Agent &…

程 控 电 源1761程控模块电源

程 控 电 源 1761程控模块电源 1761程控模块电源是在自动测试环境中提供偏置功率和对部件或最终产品提供激励的理想设备&#xff0c;是测试系统必备的测试仪器。适用于研发、设计、生产制造等自动测试领域。 1761程控模块电源为用户选配电源提供了灵活性&#xff0c;根据需要…

27岁,准备转行做网络安全渗透,完全零基础,有前途吗?

你该不该转行的问题一样&#xff0c;都是你自己的人生选择&#xff0c;怎能听人一面之词&#xff1f; 所以转行一定要想清楚&#xff0c;对自身的实力做好清晰的估算&#xff0c;换个赛道重新开始、从头再来的话&#xff0c;那么我建议你考虑“网络安全”&#xff0c;前景好薪…