0
点赞
收藏
分享

微信扫一扫

SpringCloud阿里云实现OSS

b91bff6ffdb5 2022-09-07 阅读 177

SpringCloud阿里云实现OSS

​​阿里云Github地址​​

在启动示例进行演示之前,我们先了解一下如何接入 OSS。

接入相关操作只需修改 accessKey、secretKey、endpoint 即可。

修改 pom.xml 文件,引入 aliyun-oss-spring-boot-starter。

<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>aliyun-oss-spring-boot-starter</artifactId>
</dependency>

SpringCloud整合的start为下面的

<-- 应该为下面的-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>

在配置文件中配置 OSS 服务对应的 accessKey、secretKey 和 endpoint。


// application.properties
alibaba.cloud.access-key=your-ak
alibaba.cloud.secret-key=your-sk
alibaba.cloud.oss.endpoint=***

以阿里云 accessKey、secretKey 为例,获取方式如下。

i. 在阿里云控制台界面,单击右上角头像,选择 accesskeys,或者直接登录用户信息管理界面:获取相关key信息填入

使用SpringCloud阿里云封装好的OSSClient直接进行上传

测试用例

@SpringBootTest
public class TestFor {
@Resource
OSSClient ossClient;
@Test
public void te() throws FileNotFoundException {
FileInputStream inputStream = new FileInputStream("C:\\Users\\Pictures\\903d28ab0e2f4bb59bdf8f7c6fd22fe4.jpg");
ossClient.putObject("gulimall-xuda","903d28ab0e2f4bb59bdf8f7c6fd22fe4.jpg",inputStream);
ossClient.shutdown();
System.out.println("上传完成");
}
}

注意:如果您使用了阿里云 STS服务 进行短期访问权限管理,则除了 accessKey、secretKey、endpoint 以外,还需配置 securityToken。

注入 OSSClient 并进行文件下载操作。

 @Service
public class YourService {
@Autowired
private OSSClient ossClient;

public void saveFile(){
// download file to local
ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File("pathOfYourLocalFile"));
}
}

说明:直接注入OSSClient 方式通常用于大量文件对象操作的场景。如果仅仅是需要读取文件对象内容,OSS Starter 也支持以 Resource 方式读取文件, 前后端整合进行阿里云OSS

SpringCloud阿里云实现OSS_上传

上传流程阿里云对象存储-服务端签名后直传

通常我们是前端将图片数据上传到后端再通过后端上传到OSS的,但这样直接使用服务器进行交互会使我们的服务器压力很大,

因为上传到OSS需要带上key的账户和密码,所以我们可以向服务器上传我们的请求,服务器将OSSkey生成一个签名数据返回给前端,前端将图片与签名数据进行携带直接与阿里云OSS进行交互上传,这样可以更快更节省服务器压力 可以参考下列文档 阿里云OSS服务端签名直传地址 在这里插入图片描述 网关设置

使用到nacos作为服务注册,gateway网关作为服务分发

spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: test_route
uri: https://www.baidu.com
predicates:
- Query=url,baidu

- id: third_party_route
uri: lb://gulimall-third-party
predicates:
- Path=/api/thirdparty/**
filters:
- RewritePath=/api/thirdparty/(?<segment>.*),/$\{segment}

application:
name: gulimall-gateway

server:
port: 89

网关配置跨域请求权限

package com.xuda.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

/**
* @author :程序员徐大大
* @description:统一配置跨域请求
* @date :2022-07-19 22:21
*/
@Configuration
public class CoresConfigur {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration coresConfiguration = new CorsConfiguration();
//配置跨域
coresConfiguration.addAllowedHeader("*");
coresConfiguration.addAllowedMethod("*");
// coresConfiguration.addAllowedOrigin("*");
//allowedOriginPatterns
coresConfiguration.addAllowedOriginPattern("*");
coresConfiguration.setAllowCredentials(true);
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",coresConfiguration);
return new CorsWebFilter(urlBasedCorsConfigurationSource);
}
}

创建第三方OSS项目

创建yml相关配置

spring:
cloud:
alicloud:
access-key: your-key
secret-key: your-key
oss:
endpoint: oss-cn-shanghai.aliyuncs.com
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: third-party
server:
port: 8900

编写回调OSS签名密钥代码

package com.xuda.thirdparty.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.xuda.common.utils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* @author :程序员徐大大
* @description:TODO
* @date :2022-07-21 21:35
*/
@RestController
public class OssController {

@Resource
private OSSClient ossClient;

@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint;

@Value("${spring.cloud.alicloud.access-key}")
private String accessId;

@RequestMapping("/oss/policy")
public R policy() {
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。

// 填写Bucket名称,例如examplebucket。
String bucket = "gulimall-xuda";
// 填写Host地址,格式为https://bucketname.endpoint。
String host = "https://" + bucket + "."+ endpoint;
// 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
// String callbackUrl = "https://192.168.0.0:8888";
// 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
//将日期作为上传的文件夹目录
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dir = format+"/";
Map<String, String> respMap = null;
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);

respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
// respMap.put("expire", formatISO8601Date(expiration));

} catch (Exception e) {
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
}
return R.ok().put("data",respMap); //创建返回JSON数据封装
}
}

JSON返回代码

package com.xuda.common.utils;

import org.apache.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
* 返回数据
*
*/
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;

public R(){
put("code", 0);
put("msg", "success");
}

public static R error(){
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}

public static R error(String msg){
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}

public static R error(int code, String msg){
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}

public static R ok(String msg){
R r = new R();
r.put("msg", msg);
return r;
}

public static R ok(Map<String, Object> map){
R r = new R();
r.putAll(map);
return r;
}

public static R ok(){
return new R();
}

public R put(String key, Object value){
super.put(key, value);
return this;
}
}

前端VUE代码示例

<template>
<el-dialog
:title="!dataForm.brandId ? '新增' : '修改'"
:close-on-click-modal="false"
:visible.sync="visible"
>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="140px"
>
<el-form-item label="品牌名" prop="name">
<el-input v-model="dataForm.name" placeholder="品牌名"></el-input>
</el-form-item>
<el-form-item label="品牌logo地址" prop="logo">
<single-upload v-model="dataForm.logo"></single-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</span>
</el-dialog>
</template>

<script>

import SingleUpload from "@/components/upload/singleUpload";
export default {
components: { SingleUpload },
data() {
return {
visible: false,
dataForm: {
brandId: 0,
name: "",
logo: "",
},
dataRule: {
name: [{ required: true, message: "品牌名不能为空", trigger: "blur" }],
logo: [
{ required: true, message: "品牌logo地址不能为空", trigger: "blur" },
],
},
};
},
methods: {
init(id) {
this.dataForm.brandId = id || 0;
this.visible = true;
this.$nextTick(() {
this.$refs["dataForm"].resetFields();
if (this.dataForm.brandId) {
this.$http({
url: this.$http.adornUrl(
`/product/brand/info/${this.dataForm.brandId}`
),
method: "get",
params: this.$http.adornParams(),
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataForm.name = data.brand.name;
this.dataForm.logo = data.brand.logo;
}
});
}
});
},
// 表单提交
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (valid) {
this.$http({
url: this.$http.adornUrl(
`/product/brand/${!this.dataForm.brandId ? "save" : "update"}`
),
method: "post",
data: this.$http.adornData({
brandId: this.dataForm.brandId || undefined,
name: this.dataForm.name,
logo: this.dataForm.logo,
}),
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () {
this.visible = false;
this.$emit("refreshDataList");
},
});
} else {
this.$message.error(data.msg);
}
});
}
});
},
},
};
</script>

<template> 
<div>
<el-upload
action="http://gulimall-xuda.oss-cn-shanghai.aliyuncs.com"
:data="dataObj"
list-type="picture"
:multiple="false" :show-file-list="showFileList"
:file-list="fileList"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:on-preview="handlePreview">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="fileList[0].url" alt="">
</el-dialog>
</div>
</template>
<script>
import {policy} from './policy' //导入封装的请求地址 ,下面的可以直接加上
/**
import http from '@/utils/httpRequest.js'
export function policy() {
return new Promise((resolve,reject)=>{
http({
url: http.adornUrl("/thirdparty/oss/policy"),
method: "get",
params: http.adornParams({})
}).then(({ data }) => {
resolve(data);
})
});
}
*/
import { getUUID } from '@/utils' //为了使用工具导入UUID
/**
//获取uuid,需要的可以加上进行更改
export function getUUID () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
})
}

*/
export default {
name: 'singleUpload',
props: {
value: String
},
computed: {
imageUrl() {
return this.value;
},
imageName() {
if (this.value != null && this.value !== '') {
return this.value.substr(this.value.lastIndexOf("/") + 1);
} else {
return null;
}
},
fileList() {
return [{
name: this.imageName,
url: this.imageUrl
}]
},
showFileList: {
get: function () {
return this.value !== null && this.value !== ''&& this.value!==undefined;
},
set: function (newValue) {
}
}
},
data() {
return {
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: '',
// callback:'',
},
dialogVisible: false
};
},
methods: {
emitInput(val) {
this.$emit('input', val)
},
handleRemove(file, fileList) {
this.emitInput('');
},
handlePreview(file) {
this.dialogVisible = true;
},
beforeUpload(file) {
let _self = this;
return new Promise((resolve, reject) => {
policy().then(response {
console.log("响应的数据",response);
_self.dataObj.policy = response.data.policy;
_self.dataObj.signature = response.data.signature;
_self.dataObj.ossaccessKeyId = response.data.accessid;
_self.dataObj.key = response.data.dir +getUUID()+'_${filename}'; //上传所加的目录
_self.dataObj.dir = response.data.dir;
_self.dataObj.host = response.data.host;
resolve(true)
}).catch(err {
reject(false)
})
})
},
handleUploadSuccess(res, file) {
console.log("上传成功...")
this.showFileList = true;
this.fileList.pop();
this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.key.replace("${filename}",file.name) });
this.emitInput(this.fileList[0].url);
}
}
}
</script>
<style>

</style>

SpringCloud阿里云实现OSS_java_02

举报

相关推荐

0 条评论