Spring Boot整合阿里云OSS文件上传
一、注册阿里云账号并开通OSS服务
- 登录阿里云账号
- 创建一个Bucket
3. 创建子用户
- 对子用户分配权限,打开操作OSS的全部权限(也可根据业务需求进行更改)。
4. 配置上传跨域规则
- 任何来源:
*
- 允许方法:
POST
- 任何请求头Headers:
*
二、文件上传方式
-
服务器直传方式
每个OSS的用户都会用到上传服务。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。
缺点:
- 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。
- 扩展性差:如果用户数量增加,应用服务器会成为瓶颈。
- 费用高:需要准备多台应用服务器,OSS上传流量是免费的,直接上传到OSS可以节省服务器成本。
-
服务端签名后前端直传
Web前端请求签名,然后前端(如Vue)直接上传,不会对服务端产生压力,而且安全可靠。
上传回调流程:
- Web前端请求应用服务器,获取上传所需参数(如OSS的accessKeyId、policy、callback等参数)。
- 应用服务器返回相关参数。
- Web前端直接向OSS服务发起上传文件请求。
- 上传完成后,OSS服务会回调应用服务器的回调接口。
- 应用服务器返回响应给OSS服务。
- OSS服务将应用服务器回调接口的内容返回给Web前端。
-
Spring Boot整合OSS实现文件上传
- 在
pom.xml
中添加相关依赖:
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency>
- 修改Spring Boot配置文件:
- 在
aliyun:
oss:
accessKeyId: xxx # 阿里云的accessKeyId
accessKeySecret: xxx # accessKey 密码
endPoint: xxx # Endpoint
bucketName: xxx # bucket 名称
policy:
expire: 300 # 签名有效期(S)
maxSize: 10 # 上传文件大小(M)
callback: http://localhost:8080/aliyun/oss/callback # 文件上传成功后的回调地址
dir:
prefix: xxx/images/ # 上传文件夹路径前缀
- 添加OSS的相关Java配置:
@Configuration
@Component
public class OssConfig {
@Value("${aliyun.oss.endpoint}")
private String ALIYUN_OSS_ENDPOINT;
@Value("${aliyun.oss.accessKeyId}")
private String ALIYUN_OSS_ACCESSKEYID;
@Value("${aliyun.oss.accessKeySecret}")
private String ALIYUN_OSS_ACCESSKEYSECRET;
@Bean
public OSSClient ossClient() {
return new OSSClient(ALIYUN_OSS_ENDPOINT, ALIYUN_OSS_ACCESSKEYID, ALIYUN_OSS_ACCESSKEYSECRET);
}
}
- 封装前端上传策略返回对象:
public class OssPolicyResult {
private String accessKeyId;
private String policy;
private String signature;
private String dir;
private String host;
private String callback;
}
- 封装上传成功回调参数对象:
public class OssCallbackParam {
private String callbackUrl;
private String callbackBody;
private String callbackBodyType;
}
- 封装上传成功后回调结果对象:
public class OssCallbackResult {
private String filename; // 文件名称
private String size; // 文件大小
private String mimeType; // 文件的mimeType
private String width; // 图片文件的宽
private String height; // 图片文件的高
}
- 添加OSS业务接口OssService:
public interface OssService {
OssPolicyResult policy();
OssCallbackResult callback(HttpServletRequest request);
}
- OssService实现类:
@Service
public class OssServiceImpl implements OssService {
// 实现方法...
}
- 定义OssController接口:
@RestController
@RequestMapping("/aliyun/oss")
@CrossOrigin
public class AliyunOssController {
// 定义接口...
}
三、Vue文件上传测试代码
-
创建Vue项目
在控制台中输入
vue ui
,启动Vue项目图形管理界面,访问http://localhost:8000
。
2. 安装依赖:
axios
:用于发起Ajax请求。element-ui
:使用该UI组件库中的Upload组件进行文件上传。
-
在
main.js
中启用依赖:import Vue from 'vue'; import App from './App.vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from "axios"; import VueAxios from "vue-axios"; import router from './router'; import store from './store'; Vue.config.productionTip = false; Vue.use(VueAxios, axios); Vue.use(ElementUI); new Vue({ router, store, render: h => h(App) }).$mount('#app');
-
创建OssUpload组件:
<template> <el-upload class="upload-demo" :action="objData.host" :before-upload="ossPolicy" :data="objData" :file-list="fileList" list-type="picture"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> </el-upload> </template>
<script> export default { data() { return { fileList: [], objData: { OSSAccessKeyId: '', policy: '', signature: '', key: '', host: '', dir: '' } }; }, methods: { ossPolicy(file) { let _self = this; return new Promise((resolve, reject) => { this.axios.get("http://localhost:8080/aliyun/oss/policy") .then(response => { _self.objData.OSSAccessKeyId = response.data.accessKeyId; _self.objData.policy = response.data.policy; _self.objData.signature = response.data.signature; _self.objData.dir = response.data.dir; _self.objData.host = response.data.host + ''; _self.objData.key = response.data.dir + "${filename}"; resolve(true); // 继续上传 }) .catch(error => { reject(false); }); }); } } } </script>
-
在
HelloWorld.vue
中引用文件上传组件:<template> <div class="hello"> <h1>{{ msg }}</h1> <OssUpload></OssUpload> </div> </template> <script> import OssUpload from "@/components/OssUpload.vue"; export default { name: 'HelloWorld', components: { OssUpload }, props: { msg: String } } </script>
四、前后端联调
- 启动后端服务。
- 启动前端项目。
- 选择文件进行上传,确认上传成功。
4. 查看OSS Bucket,确认图片已成功存储至OSS服务中。
评论区