首先去阿里云购买对象存储OSS资源包。
供学习使用选择最低档的价格很优惠,标准型存储包5元半年。
上传不收取网络流量费用,但是当外网去访问存储的资源时,会产生下行的流量费用,因此,还需要购买下行流量包,也是选择最低档,半年60元。
先新建一个Bucket
在文件管理中,可直接上传图片,在浏览器访问到。
在图片处理中,可添加水印的样式。
在访问设置中,选择自定义分隔符,在图片路径后拼接分隔符与水印的规格名称,就能给图片添加上水印。
开启原图保护功能的话,如果把路径后的水印规则给去掉,就不能访问该图片了。
效果如下
控制台的其他监控管理等功能就不一一介绍了。
更多可阅读其开发者指南,很丰富,很多花式上传下载。
https://help.aliyun.com/document_detail/52830.html?spm=5176.8465980.home.d3.4e701450YLCAOg
这里采用简单上传,使用它的SDK与自己的项目整合。
SDK依赖:
<dependency>
<groupId>com.aliyun.ossgroupId>
<artifactId>aliyun-sdk-ossartifactId>
<version>3.4.2version>
dependency>
我们需要一个OSSClient
实例去实现上传等功能,编写配置类将其装配到Spring容器中。
在RAM访问控制中可以获取到accessKeyId与accessKeySecret。
或者就在OSS控制台概览的右侧进入,根据其提示获得。
这里使用的是SpringBoot,所以相关配置直接在application.yml中编写。
aliyun:
accessKeyId: xxxxx
accessKeySecret: xxxxxx
oss:
endpoint: http://oss-cn-shanghai.aliyuncs.com
bucketName: orcas-rent
urlPrefix: https://orcas-rent.oss-cn-shanghai.aliyuncs.com/
/**
* 用于Ali产品的配置 (OSS)
* @author: Orcas
* @version:1.0.0
* @date: 2019/4/28
*/
// @PropertySource("classpath:xxxx.properties") 默认路径下可不加
@Data
@Configuration
public class AliyunConfig {
// 地域节点
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.accessKeySecret}")
private String accessKeySecret;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.urlPrefix}")
private String urlPrefix;
@Bean
public OSSClient ossClient() {
return new OSSClient(endpoint, accessKeyId, accessKeySecret);
}
}
根据前端需要我们响应的数据创建一个上传图片返回结果类(略)。
Controller层代码略。
简单实现上传图片的功能,具体看注释。
@Service
public class UploadPicService {
// 允许上传的格式
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 multipartFile) {
// 1. 对上传的图片进行校验: 这里简单校验后缀名
// 另外可通过ImageIO读取图片的长宽来判断是否是图片,校验图片的大小等。
// TODO 图片校验
boolean isLegal = false;
for (String type : IMAGE_TYPE) {
if (StringUtils.endsWithIgnoreCase(multipartFile.getOriginalFilename(), type)) {
isLegal = true;
break; // 只要与允许上传格式其中一个匹配就可以
}
}
PicUploadResult picUploadResult = new PicUploadResult();
// 格式错误, 返回与前端约定的error
if (!isLegal) {
picUploadResult.setStatus("error");
return picUploadResult;
}
// 2. 准备上传API的参数
String fileName = multipartFile.getOriginalFilename();
String filePath = this.getFilePath(fileName);
// 3. 上传至阿里OSS
try {
ossClient.putObject(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(multipartFile.getBytes()));
} catch (IOException e) {
e.printStackTrace();
// 上传失败
picUploadResult.setStatus("error");
return picUploadResult;
}
// 上传成功
picUploadResult.setStatus("done");
// 文件名(即直接访问的完整路径)
picUploadResult.setName(aliyunConfig.getUrlPrefix() + filePath);
// uid
picUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
return picUploadResult;
}
/**
* 上传的目录
* 目录: 根据年月日归档
* 文件名: 时间戳 + 随机数
* @param fileName
* @return
*/
private String getFilePath(String fileName) {
DateTime dateTime = new DateTime();
return "images/" + dateTime.toString("yyyy") + "/" + dateTime.toString("MM") + "/"
+ dateTime.toString("dd") + "/" + System.currentTimeMillis() +
RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(fileName, ".");
}
代码编写完成后,用Insomnia进行调试。
需要注意两点,设置Header。Content-Type: multipart/form-data。
还有就是设置与Controller接口中请求约定的@RequestParam("file")
中的 file。
成功在浏览器中访问到
这个时候我们去控制台文件管理中也可看到上传的文件
调试过程中遇到过一个报错,忘了截图了,根据我百度的历史记录找到了这段关键句:
You have no right to access this object because of bucket acl.
这是因为我在控制台创建用户的时候并没有给他授权,可在RAM访问控制中进行设置。