前言
在正式的开发环境中,类似图片的静态资源一般不会存放在项目部署的服务器端,因为这样会占用大量的资源。所以我们一般使用第三方的云存储服务来实现静态资源的存取。本篇来记录使用阿里云OSS实现图片上传的案例。
一、OSS是什么?
阿里云OSS是一款,由阿里巴巴提供的云存储解决方案。云存储的优势在于,不用消耗本地服务器资源,高效,海量,低成本,高可靠,使用起来非常方便。
二、使用步骤
1.开通OSS服务
首先我们需要登陆阿里云官方网站,去登陆,没有帐号注册一个即可。然后需要进行余额充值,因为OSS服务是付费产品。
登陆完成,找到对象存储OSS服务进行开通
2.创建bucket
bucket就是我们需要存储文件的容器
3.创建子账户
帐号是我们访问OSS的凭证,推荐创建子账号进行资源访问
点击创建用户
我们需要为子账户添加权限,让其可以访问OSS
4.查看帮助文档,编写后端代码
我们找到帮助文档
进入帮助文档,找到SDK示例
导入maven依赖
选择java版本,简单上传
选择,上传文件流
将代码复制,在IDEA新建一个工具类,粘贴,需要注意的是,要将id和密钥换成自己的
package com.lzl.util;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* @date 2022/10/11
* @desc
*/
public class OssUtil {
public static String uploadFile(InputStream inputStream, String filename) {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "";
String accessKeySecret = "";
// 填写Bucket名称,例如examplebucket。
String bucketName = "";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "image/";
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
//String filePath = "E:\\2212\\pic\\girl.jpg";
objectName = objectName+System.currentTimeMillis()+filename.substring(filename.lastIndexOf("."));
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,objectName, inputStream);
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
// 上传文件。
ossClient.putObject(putObjectRequest);
//得到上传之后的文件地址
//https://bucketname.endpoint/objectnane https://upload-demo-liu.oss-cn-hangzhou.aliyuncs.com
String fileUrl = "自己的路径"+objectName;
System.out.println("上传之后的文件路径"+ fileUrl);
return fileUrl;
} 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 "上传失败";
}
}
controller代码:
/**
* @param file
* @return 文件路径
* @throws IOException
*/
@PostMapping("/upload")
@ResponseBody
public ResultLayUi<String> uploadPic(MultipartFile file) throws IOException {
//得到文件的名字
String originalFilename = file.getOriginalFilename();
String fileUrl = OssUtil.uploadFile(file.getInputStream(), originalFilename);
// 上传成功之后的文件地址 写给前端
ResultLayUi<String> resultLayUi = new ResultLayUi<>();
resultLayUi.setCode(0);
resultLayUi.setT(fileUrl);
return resultLayUi;
}
5.layui前端
此处使用layui作为前端的上传页面,需要引入Layui环境
页面结构:
<div class="layui-form-item">
<label class="layui-form-label">图片名字:</label>
<div class="layui-input-block">
<input type="hidden" name="path" value="" id="path" />
<input type="text" name="pname" lay-verify="required" class="layui-input" style="width:200px;" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<!--图片上传div-->
<div class="layui-upload">
<button type="button" class="layui-btn" id="test1">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="demo1">
<p id="demoText"></p>
</div>
<div style="width: 95px;">
<div class="layui-progress layui-progress-big" lay-showpercent="yes" lay-filter="demo">
<div class="layui-progress-bar" lay-percent=""></div>
</div>
</div>
</div>
</div>
</div>
js处理
//常规使用 - 普通图片上传
var uploadInst = upload.render({
elem: '#test1'
, url: 'http://localhost:8080/picture/upload' //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
, before: function (obj) {
//预读本地文件示例,不支持ie8
obj.preview(function (index, file, result) {
$('#demo1').attr('src', result); //图片链接(base64)
});
element.progress('demo', '0%'); //进度条复位
layer.msg('上传中', { icon: 16, time: 0 });
}
, done: function (res) {
//如果上传失败
if (res.code > 0) {
return layer.msg('上传失败');
}else{
//上传成功的一些操作
$("#path").val(res.t);
}
//……
$('#demoText').html(''); //置空上传失败的状态
}
, error: function () {
//演示失败状态,并实现重传
var demoText = $('#demoText');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
//进度条
, progress: function (n, elem, e) {
element.progress('demo', n + '%'); //可配合 layui 进度条元素使用
if (n == 100) {
layer.msg('上传完毕', { icon: 1 });
}
}
});
测试如下:
成功!
总结
使用OSS对象存储服务来实现文件的上传是必须要掌握的。下篇再见