赞
踩
实现图片上传服务,需要有存储的支持,那么我们的解决方案将以下几种:
直接将图片保存到服务的硬盘
优点:开发便捷,成本低
缺点:扩容困难
使用分布式文件系统进行存储
优点:容易实现扩容
缺点:开发复杂度稍大(有成熟的产品可以使用,比如:FastDFS)
使用nfs做存储
优点:开发较为便捷
缺点:需要有一定的运维知识进行部署和维护
使用第三方的存储服务
优点:开发简单,拥有强大功能,免维护
缺点:付费
阿里云OSS存储
官方参考文档:https://help.aliyun.com/product/31815.html
注意 开通 OSS 服务后,默认的计费方式是按量付费。如果想降低 OSS 费用,建议您购买资源包 。
使用OSS,首先需要创建Bucket,Bucket翻译成中文是水桶的意思,把存储的图片资源看做是水,想要盛水必须得有桶,就是这个意思了。存储空间(Bucket)是用于存储对象(Object)的容器,可以存储若干文件。所以在上传任何文件到OSS之前,您必须先创建存储空间。
以下步骤可以查看阿里云的视频教学:
https://help.aliyun.com/learn/learningpath/oss.html?spm=5176.11888651.1190625.4.44623a4cD6hbPy
进入控制台,https://oss.console.aliyun.com/overview
选择Bucket后,即可看到对应的信息,如:url、消耗流量等 :
Endpoint:上传文件时使用
Bucket域名:查看文件时使用
文件管理:
删除 Bucket
由于我们在创建Bucket的时候,读写权限设置的是公共读,意味着写操作,也就是上传文件的操作不能直接进行,而是需要通过身份认证,对象存储服务器需要认证你的身份信息,如果
身份是合法的,才可以继续上传文件的操作。身份认证认证的是当前登录的用户,也就是谁开通的对象存储服务,就认证谁的用户信息。
一般来说我们不直接认证当前登录的用户,也就是谁开通的对象存储服务的用户,而是通过创建一个访问控制(RAM)的账号,也叫当前登录用户的子账号,通过子账号来控制对文件的操作权限。如果将主账号提供出去,那也就意味着,谁都可以访问对象存储服务,同时这个主账号开通的其他服务,比如云服务ECS等等都可以进行访问。
所以我们创建当前登录用户主账号的子账号来针对只能访问对象存储OS服务的操作权限,从而降低风险。
创建用户的方式与短信接口中的方式一样,创建完用户之后需要设置oss权限。
务必保存好这两个数据 因为此页面一旦刷新,就再也查不到此用户的的AccessKey ID和 AccessKey Secret。
如果创建用户时,没有保存到 AccessKeyID 和 AccessKeySecret ,需要重新创建,步骤如下:
进入后,认证管理 标签页下面点击 创建新的 AccessKey
通过手机号安全认证之后,就能重新获取AccessKey ID和 AccessKey Secret
设置oss权限
阿里云OSS开发文档
以上对于阿里云OSS基础的准备工作已经做好了,下面实现代码部分
第一步
导⼊依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.0</version>
</dependency>
第二步
创建存储空间
OSS配置-在application.yml配置文件当中进行配置
//第1项配置 # 要带上 https:// ,上传时要使用的 aliyun.endpoint = https://*************** //第2项配置 # 根据自己的帐号配置 aliyun.accessKeyId = *********** //第3项配置 # 根据自己的帐号配置 aliyun.accessKeySecret = *************** //第4项配置 # 存储空间名称 aliyun.bucketName= *************** //第5项配置 # Bucket域名,访问文件时作为URL前缀,注意要加上 https:// 和 结尾带上 / aliyun.urlPrefix=https://***************/
以上需要在代码当中配置5项,我们来分别说下这5项代表的是什么:
第1项和第5项如下:
第2和第3项是我们新创建的个人用户的accessKeyId和accessKeySecret
第4项就是我们创建的Bucket名称
我们将这5项数据配置在代码的配置文件aliyun.properties当中,通过配置类去加载这5项消息
配置类
@Configuration @PropertySource("classpath:aliyun.properties") @ConfigurationProperties(prefix = "aliyun") @Data public class AliyunConfig { private String endpoint; private String accessKeyId; private String accessKeySecret; private String bucketName; private String urlPrefix; @Bean public OSSClient oSSClient() { return new OSSClient(endpoint, accessKeyId, accessKeySecret); } }
控制器:
@RequestMapping("pic/upload")
@Controller
public class PicUploadController {
@Autowired
private PicUploadService picUploadService;
@PostMapping
@ResponseBody
public PicUploadResult upload(@RequestParam("file") MultipartFile multipartFile) {
return this.picUploadService.upload(multipartFile);
}
}
vo:
@Data
public class PicUploadResult {
// 文件唯一标识
private String uid;
// 文件名
private String name;
// 状态有:uploading done error removed
private String status;
// 服务端响应内容,如:'{"status": "success"}'
private String response;
}
service:
@Service public class PicUploadService { // 允许上传的格式 private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg", ".jpeg", ".gif", ".png"}; @Autowired private OSSClient ossClient; @Autowired private AliyunConfig aliyunConfig; public PicUploadResult upload(MultipartFile uploadFile) { PicUploadResult fileUploadResult = new PicUploadResult(); //图片做校验,对后缀名 boolean isLegal = false; //对上传的图片后缀名做校验 for (String type : IMAGE_TYPE) { if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) { isLegal = true; break; } } //不支持格式的上传 if (!isLegal) { fileUploadResult.setStatus("error"); return fileUploadResult; } // 文件新路径 String fileName = uploadFile.getOriginalFilename(); String filePath = getFilePath(fileName); // 上传到阿里云 try { // 目录结构:images/2018/12/29/xxxx.jpg ossClient.putObject(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(uploadFile.getBytes())); } catch (Exception e) { e.printStackTrace(); //上传失败 fileUploadResult.setStatus("error"); return fileUploadResult; } // 上传成功 fileUploadResult.setStatus("done"); fileUploadResult.setName(this.aliyunConfig.getUrlPrefix() + filePath); //一般这个生成的id我们会将保存在数据库当中 fileUploadResult.setUid(String.valueOf(System.currentTimeMillis())); return fileUploadResult; } //创建文件新的路径 private String getFilePath(String sourceFileName) { DateTime dateTime = new DateTime(); //images/yyyy/MM/dd/xxxxxxx.jpg return "images/" + dateTime.toString("yyyy") + "/" + dateTime.toString("MM") + "/" + dateTime.toString("dd") + "/" + System.currentTimeMillis() + RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, "."); } }
测试:
查看OSS服务器当中是否存在此图片
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。