B087-人力资源项目-文件上传课程分类

目录

      • 背景
      • 控制台操作
        • 开通OSS服务
        • 创建存储空间
      • 项目工程准备
        • 概述
        • 新建文件管理模块
        • 把文件上传到OSS的三种方案
      • 通过官方文档完成demo上传
        • 官方文档找JavaSDK
        • 文件上传思路
        • 代码

背景

为什么要交给第三方文件管理服务管理?

最传统的的文件管理方案是把文件存储到项目中本地 “/webapp/upload/”,把文件的地址保存到数据库,客户端获取到图片的地址就可以浏览或者下载文件。这种管理方式是把文件交给应用本身来处理,文件不仅要占用应用服务器的空间资源,文件的读取以及把文件响应给客户端给应用服务器也带来很大的压力,并且在分布式/集群环境中存在文件不共享的问题。

在分布式/集群环境中需要采用统一的文件处理方案,文件不需要应用本身来管理,而是交给专门的文件服务器来实现文件的上传,下载以及删除操作,这样的好处是应用服务器不再处理图片压力减轻,图片不会占用应用服务器本身的空间资源,并且统一的文件服务器实现的文件的共享,所有的微服务都可以通过文件服务器来上传和下载文件。

另外第三方文件管理服务服务完善,包括图片鉴黄,处理政治,邪教,传销等敏感信息,图片瘦身,水印等。

为什么没再用fastDFS,大城市大企业很少用,成本也不低。自己搭的出了问题需要自己维护,没有第三方稳定。

阿里云OSS处理方案:https://blog.csdn.net/u014494148/article/details/108858360

官方文档:https://help.aliyun.com/document_detail/31886.html

控制台操作

开通OSS服务

阿里云官网 - 产品 - 存储 - 对象存储 OSS - 立即开通/管理控制台(由于已经开通)

创建存储空间

Bucket 列表 - 创建bucket(注意名称不要写中文 最好英文字母加数字 也可以加横杠)
在这里插入图片描述
进入创建好的存储空间,可以先测试一下使用功能
在这里插入图片描述

项目工程准备

概述

在微服务架构中把文件相关操作功能单独做一个服务,系统中所有模块只要涉及文件的上传都走同一个服务
在这里插入图片描述
存在两种情况:1.前端直接访问文件服务,2.服务之间文件的上传,(用到feign,融合了ribbon和hystrix)

新建文件管理模块

作为父工程把src删掉,
设置打包方式:< packaging >pom< /packaging >,这样不会打成jar包,只是去维护工程中的公共坐标
在这里插入图片描述

把文件上传到OSS的三种方案

1.通过web前端直接上传到OSS服务器,这种方式意味着需要把OSS配置参数写死在JS中,有安全隐患
2.通过web前端把文件上传到后端服务器,后端服务器再把文件上传到OSS,这种方式虽然没有了暴露OSS配置参数的安全隐患,但是文件通过后端中转了一次在上传,性能不高,而且增加了服务的压力.影响不大,我们用第二种
3.OSS最佳实践:后端服务签名后前端直传,即:依然是web前端直接把文件上传到OSS服务器,只是在上传文件之前先请求后端获取OSS配置签名信息,web前端拿到签名信息后和文件一起上传到OSS服务器,这样一来,文件上传既不需要通过后台服务器中转一次,也不会有暴露OSS配置参数的风险。

通过官方文档完成demo上传

官方文档找JavaSDK

https://help.aliyun.com/document_detail/31886.html

文件上传思路

1.前端发起一个上传的请求
2.前端将上传的文件以IO流的方式,传到后台
3.后台会以MultipartFile的数据类型来接收
4.进行文件保存
使用OSS的对象存储来实现

代码

在这里插入图片描述
application.yml

server:
  port: 1050

file:
  alicloud:
    bucketName: hrm-obj-ming #上传空间bucket
    accessKey: aaaaaaaaaaaaaaaaaaaaa #key
    secretKey: sssssssssssssssssssss #秘钥
    endpoint: https://oss-cn-beijing.aliyuncs.com  #上传端点

AlicloudOSSProperties

@Data
@Component //这个注解不能省略。将这个对象的创建过程交给Spring管理。只有这样你才能在需要使用它的地方,通过@autowired进行注入
@ConfigurationProperties(prefix = "file.alicloud") //读取application.yml中自定义的属性,并设置它的前缀
public class AlicloudOSSProperties {
    private String bucketName;
    private String accessKey;
    private String secretKey;
    private String endpoint;
}

FileController

@RestController
@RequestMapping("/file")
public class FileController {

/*    @Value("${file.alicloud.buketName}")
    private String buketName;
    @Value("${file.alicloud.accessKey}")
    private String accessKey;
    @Value("${file.alicloud.secretKey}")
    private String secretKey;
    @Value("${file.alicloud.endpoint}")
    private String endpoint;*/

    @Autowired
    private AlicloudOSSProperties alicloudOSSProperties;

    @PostMapping("/upload1")
    private AjaxResult upload1(MultipartFile file,String objectPath){
        // Endpoint按实际情况填写。
        String endpoint = "https://oss-cn-beijing.aliyuncs.com";
        String accessKeyId = "kkkkkkkkkkkkkkkkkkk";
        String accessKeySecret = "sssssssssssssssssssssss";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        try {
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        } catch (com.aliyuncs.exceptions.ClientException e) {
            e.printStackTrace();
        }
        // 填写Bucket名称
        String bucketName = "hrm-obj-ming";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String suffix = StringUtils.substringAfter(file.getOriginalFilename(), ".");
        String objectName = objectPath + resetFileName() + "." + suffix;
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
        String localPath = "D:/devPicture/pethome/";
        String localFileWholeName = localPath + file.getOriginalFilename();

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

        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(localFileWholeName));
            // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
            // ObjectMetadata metadata = new ObjectMetadata();
            // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
            // metadata.setObjectAcl(CannedAccessControlList.Private);
            // putObjectRequest.setMetadata(metadata);

            // 上传文件。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            System.out.println("result = " + result);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return new AjaxResult().setMessage("上传成功了");
    }

    @PostMapping("/upload2")
    public AjaxResult upload2(String objectPath,MultipartFile file) throws Exception {
/*        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = "https://oss-cn-beijing.aliyuncs.com";
        // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
        String accessKeyId = "kkkkkkkkkkkkkkkk";
        String accessKeySecret = "ssssssssssssssss";*/

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(alicloudOSSProperties.getEndpoint(), alicloudOSSProperties.getAccessKey(), alicloudOSSProperties.getSecretKey());

        // 填写Byte数组。
        byte[] content = file.getBytes();
        // 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
        //注意:所有有关字符串的操作,尽量使用commons-lang3包中stringutils工具类
        //abc.png-----拿到.png
        String suffix = StringUtils.substringAfter(file.getOriginalFilename(), ".");
        String ossWholeFileName = objectPath + resetFileName() + "." + suffix;
        ossClient.putObject(alicloudOSSProperties.getBucketName(), ossWholeFileName, new ByteArrayInputStream(content));

        // 关闭OSSClient。
        ossClient.shutdown();

        return AjaxResult.me().setResultObj(ossWholeFileName);
    }

    /**
     * 生成一个唯一的文件的名称:年+月+日+随机串
     * @return
     */
    private String resetFileName() {
        //如何获取年月日
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String format = sdf.format(new Date());
        //再通过UUID得到一个随机且唯一的字符串
        String randomStr = StringUtils.replace(UUID.randomUUID().toString(), "-", "");
        return format + randomStr;
    }
}

pom.xml

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

半小时拥有自己的ChatGPT4,高效低成本,无脑跟即可

文章目录 一、获取Key二、获取服务器三、设置端口三、安装Docker环境 一、获取Key 最简单的获取方法&#xff0c;去某宝搜 “open账号ai” 购入一个key&#xff0c;几块钱&#xff0c;有3.5、4.0&#xff0c;买3.5就行了&#xff0c;4.0太贵了。注意是购入key&#xff0c;不是…

Elasticsearch 和 Go 中使用向量搜索寻找地鼠

作者&#xff1a;CARLY RICHMOND&#xff0c;LAURENT SAINT-FLIX 就像动物和编程语言一样&#xff0c;搜索也经历了不同实践的演变&#xff0c;很难在其中做出选择。 加入我们的第二部分&#xff0c;通过 Elasticsearch 中的矢量搜索在 Go 中狩猎地鼠&#xff08;gophers&…

Install Docker in Linux

Docker官网链接: https://docs.docker.com/ 1.确定Linux版本 新版本的Docker对Linux系统版本有一定的要求。如果Linux的发行版系统是centOS&#xff0c;安装最新版的docker需要centOS 7以上的系统。 在Docker安装帮助页面查看支持的系统版本。 Docker帮助页面:https://docs…

13 套接字Socket

1、Socket 编程 socket编程基于 TCP 和 UDP 协议的tcp和udp是区分客户端和服务端的&#xff0c;所以我们的socket编程也是区分的。 2、socket是端到端的通信 1.Socket 这个名字很有意思&#xff0c;可以作插口或者插槽讲 2.一头插在客户端&#xff0c;一头插在服务端&#x…

拉晶工艺设备——切片机

单晶炉拉出硅棒后&#xff0c;经硅棒切断、外园整形&#xff0c;便用切片机切成薄片&#xff0c;供后续工艺使用。切片机也用于玻璃、陶瓷、 大理石、花岗岩等硬脆材料的切割。 半导体行业使用的切片机按结构形式可分为立式切片机、卧式切片机&#xff0c;按刀片形式可分内圆切…

魔众文库系统 v5.5.0 批量快捷上传,文档图标优化,档转换逻辑优化

魔众文库系统基于文档系统知识&#xff0c;建立平台与领域&#xff0c;打造流量、用户、付费和变现的闭环&#xff0c;帮助您更好的搭建文库系统。 魔众文库系统发布v5.5.0版本&#xff0c;新功能和Bug修复累计14项&#xff0c;批量快捷上传&#xff0c;文档图标优化&#xff…

酷柚易汛ERP - 套餐管理操作指南

1、应用场景 套餐管理应用于商品打包销售&#xff0c;如临期食品&#xff0c;促销商品等 2、主要操作 2.1 新增套餐 打开【资料】-【套餐管理】点击新增 套餐是一个组合新商品出现&#xff0c;价格需要重新设定&#xff0c;也可以设定不同等级客户对应价格

SAP ABAP基础语法-Excel上传(十)

EXCEL BDS模板上传及赋值 上传模板事务代码&#xff1a;OAER l 功能代码&#xff1a;向EXCEL模板中写入数据示例代码如下 REPORT ZEXCEL_DOI. “doi type pools TYPE-POOLS: soi. *SAP Desktop Office Integration Interfaces DATA: container TYPE REF TO cl_gui_custom_c…

arduino 简易智能花盆

编辑器&#xff1a;arduino IDE 主板&#xff1a;arduino uno 传感器&#xff1a; 0.96寸的OLED屏&#xff08;四脚&#xff09; 声音模块 土壤温湿度模块 DS18B20温度模块&#xff08;这里用到防水的&#xff09; 光敏电阻模块&#xff08;买成三脚的了只能显示高低&#x…

软件测试的终点是“测试开发”吗?

前言 在一线大厂&#xff0c;没有测试这个岗位&#xff0c;只有测开这个岗位&#xff0c;即使是做业务测试&#xff0c;那么你的title也是测开。 所以想聊一聊测开的看法&#xff0c;但不代表这是正确的看法&#xff0c;仅供参考。 没来阿里之前我对测开的看法 一直以为专职做自…

软件测试金融项目,在测试的时候一定要避开的一些雷区

软件测试金融项目需要格外谨慎和专注&#xff0c;因为这些项目通常涉及大量的交易、用户隐私和其他敏感信息。以下是一些软件测试金融项目时需要关注的方面&#xff1a; 1. 数据保护 在测试金融项目时&#xff0c;必须确保用户数据和投资信息得到保护。测试人员必须确保测试环…

我干了8年测试,告诉你现在软件测试还能不能找到工作!

观点&#xff1a;如果你还是以前的思维来学习测试&#xff0c;那你肯定是找不到工作&#xff01; 我做测试工作有将近8年的时间&#xff0c;蚂蚁金服做过2年&#xff0c;因为加班太多离职了。目前在一家国企上市公司&#xff0c;一年能拿三四十个左右&#xff0c;对比头部互联…

信息系统“好用”的标准探讨

数字化转型建设的关键不在建设信息系统。这是为了避免走信息化建设的老路——业务和信息化两张皮&#xff0c;寄希望信息系统解决业务问题。在数字化转型建设中&#xff0c;信息系统仍然是重要抓手和显性成果&#xff0c;是企业业务和数据的承载平台&#xff0c;也是IT厂商向客…

李峋同款的C语言动态爱心代码来了,彩色闪动,附源码

1.前言 最近一部电视剧《点燃我&#xff0c;温暖你》可火啦&#xff0c;大家纷纷在搞男主阿瑟的同款爱心代码&#xff0c;但是虽然网上有它的源码&#xff0c;但都不是 C 语言的&#xff0c;看不懂。我看了一下这个视频&#xff0c;大致分析了一下它的运行过程。用语言描述一下…

【C++】C++11常用特性梳理

C11特性梳理 1. 列表初始化2. auto & decltype3. 右值引用3.1. 左右值引用比较3.2. 右值引用的意义3.3. 万能引用与完美转发3.4. 移动构造与移动赋值 4. default & delete5. 可变参数模板6. push_back 与 emplace_back7. lambda表达式7.1. 捕捉列表 8. function包装器8…

(一)QML加载离线地图+标记坐标点

1、实现效果 加载离线地图瓦片、鼠标拖拽、滚轮缩放在地图上固定坐标位置标注地名 &#xff08;一&#xff09;QML加载离线地图标记坐标点&#xff1a;MiniMap-mini 2、实现方法 2.1、使用工具下载离线地图 不废话&#xff0c;直接搬别人的砖&#xff0c;曰&#xff1a;他山…

VirtualBox网络地址转换(NAT),宿主机无法访问虚拟机的问题

问题&#xff1a;NAT模式下&#xff0c;默认只能从内访问外面&#xff0c;而不能从外部访问里面&#xff0c;所以只能单向ping通&#xff0c;虚拟机的ip只是内部ip。 PS&#xff1a;桥接则是与主机公用网卡&#xff0c;有独立的外部ip。 解决&#xff1a;NAT模式可以通过配置 …

好物周刊#30:Github 上大学

https://github.com/cunyu1943/JavaPark https://yuque.com/cunyu1943 村雨遥的好物周刊&#xff0c;记录每周看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;每周五发布。 一、项目 1. Fighting Design 一款灵活、优质的组件库&#xff0c;可在 vue3 应用程…

【api_fox】ApiFox简单操作

1、get和post请求的区别&#xff1f;2、接口定义时的传参格式&#xff1f;3、保存接口文档 apifox当中接口文档的设计和接口用例的执行是分开的。 1、get和post请求的区别&#xff1f; 2、接口定义时的传参格式&#xff1f; 3、保存接口文档 就生成如下的接口文档。

C语言实现编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n

完整代码&#xff1a; /*编写一个函数&#xff0c;输入n为偶数时&#xff0c;调用函数求1/21/4...1/n,当输入n为奇数时&#xff0c; 调用函数1/11/3...1/n */ #include<stdio.h>//n为偶数 double Odd(int n){double sum0;//i为2&#xff0c;4&#xff0c;6....for (int …