目录
1. 前言:
-> 1.1 前端上传优势:
2. 下面介绍一种普通上传方式:
-> ps: 配合前端进行上传:
-> 2.1 流程:
-> 2.2 查看微信小程序官方文档
-> 2.2.1 微信小程序官网位置
---> 2.2.2 看看前端都需要什么参数
-> 2.3 后端目标明确,开整
3. 具体实现
-> 3.1 entity实体类参数
-> 3.2 controller 控制层
-> 3.3 service的 impl层
-> 3.4 OssUtils封装方法
ps: host位置特别注意一下:
4. 回调的url是什么???
-> 4.1 回调url 则是 前端上传后路径, 后台给返回的呦~~~
->4.2 什么什么, 不能访问 报错了???
-> 4.3 到此 游戏结束了
前端上传可以减少服务端压力,因为带宽是比较贵的。如果文件上传频率很高,很可能造成带宽不够,上传缓慢问题,影响用户体验。
前端需要啥就给啥, 咱们不多想 整就完了
前端请求后端获取一个token(有时效性),之后通过这个token来给阿里云鉴权,然后上传文件;这样将不会直接将accessKeyId和accessKeySecret直接暴露给用户了, js是不安全的
链接跳转: 如何在微信小程序环境下将文件上传到OSS_对象存储-阿里云
参数 | 是否必选 | 说明 |
---|---|---|
host | 是 | 填写Bucket的访问域名,例如https://examplebucket.oss-cn-zhangjiakou.aliyuncs.com 。如果您的Bucket已绑定自定义域名,建议填写您的自定义域名。 |
signature | 是 | 填写步骤3中获取到的signature信息。 |
ossAccessKeyId | 是 | 填写您的AccessKey ID。如果您是通过STS获取的临时用户,则填写临时用户的AccessKey ID。 |
policy | 是 | 填写步骤3中获取到的policy信息。 |
key | 是 | 设置文件上传至OSS后的文件路径。例如,您需要将myphoto.jpg上传至test文件夹下,则填写test/myphoto.jpg 。 |
securityToken | 是 | 如果使用STS认证,则填写步骤3中使用客户端签名获取到的SecurityToken。 |
filePath | 是 | 填写待上传文件的本地完整路径,例如D:\example.txt 。 |
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* oss认证请求token秘钥等信息
*
* @Author pzy
* @Description: TODO
* @Version 0.1.0
*/
@ApiModel(value = "oss认证请求token秘钥等信息")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class OssTokenReqDTO {
@ApiModelProperty("上传路径url")
private String uploadUrl;
@ApiModelProperty("上传文件大小kb")
private Integer fileSize;
@ApiModelProperty("文件后缀名")
private String suffixName;
@ApiModelProperty("是否加密 默认不加密")
private Boolean isSecret = Boolean.FALSE;
}
我这里不推荐使用是 因为前端还没准备好 嘿嘿
ResultResponse 随便啥, 返回值的类型, 写String都行, 这里就不提供了
@Deprecated
@ApiOperation("测试版... 前端oss 返回需要的秘钥")//暂不推荐使用
@RequestMapping(value = "/getGenerateToken", method = RequestMethod.POST)
public ResultResponse getGenerateToken(@RequestBody OssTokenReqDTO ossTokenReqDTO){
log.info("===> 前端oss 返回需要的秘钥<===");
return ossAddService.getGenerateToken(ossTokenReqDTO);
}
/**
* 引入秘钥等 js代码解密 密钥对
* @param ossTokenReqDTO
* @return
*/
@Override
public ResultResponse getGenerateToken(OssTokenReqDTO ossTokenReqDTO) {
//其他业务操作的延伸
log.info("" + ossTokenReqDTO);
Map map = OSSUtils.generateToken(ossTokenReqDTO);
/*校验: 是否加密 默认不开启加密*/
if (ossTokenReqDTO.getIsSecret()) {
String str = CryptoUtils.aesEncryptForFront(String.valueOf(map), CryptoUtils.KEY_DES);
log.info(CryptoUtils.aesDecryptForFront(str, CryptoUtils.KEY_DES));
return ResultResponse.ok("查询成功!").setData(str);
}
return ResultResponse.ok("查询成功!").setData(map);
}
ps: 中间的if校验 先 !!! 注释掉 !!! , 先不加密(下文再说) 链接!!!!!!!
创建文件 加上注解@Slf4j @Component
/**
* pzy 20230410
* 生成前端oss上传校验token 测试版
* 是否需要加密解密
*
* @param ossTokenReqDTO
* @return
*/
public static Map generateToken(OssTokenReqDTO ossTokenReqDTO) {
// 授权访问oss的ack
String accessId = accessKeyId;
String accessKey = accessKeySecret;
String bucket = bucketName;
// 格式为https://bucketname.endpoint,例如https://bucket-name.oss-cn-chengdu.aliyuncs.com
String[] split = endpoint.split("//");
String host = "https://" + bucket + "." + split[1];
// 要上传的目录,比如:train
String dir = StringUtils.isNotBlank(ossTokenReqDTO.getUploadUrl()) ? ossTokenReqDTO.getUploadUrl() : ossFileUploadUrl(null);
// 设置token的过期时间,这里设置的1分钟
long expireEndTime = System.currentTimeMillis() + 60 * 1000;
Date expiration = new Date(expireEndTime);
// 设置生成token的权限
PolicyConditions policyConditions = new PolicyConditions();
policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConditions.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
// 创建oss请求对象
OSS client = new OSSClientBuilder().build(endpoint, accessId, accessKey);
// 发送请求获取token
String postPolicy = client.generatePostPolicy(expiration, policyConditions);
// 解析请求响应
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
// 政策信息
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
// 签名信息
String postSignature = client.calculatePostSignature(postPolicy);
log.info("accessKeyId:" + accessId);
log.info("encodedPolicy:" + encodedPolicy);
log.info("postSignature:" + postSignature);
log.info("dir:" + dir);
log.info("host:" + host);
log.info("expire:" + (expireEndTime / 1000));
Map map = new ConcurrentHashMap<>();
map.put("accessKeyId", accessId);
map.put("encodedPolicy", encodedPolicy);
map.put("postSignature", postSignature);
map.put("dir", dir);
map.put("host", host);
map.put("expire", String.valueOf((expireEndTime / 1000)));
map.put("filePath", dir + "/" + IdGenerater.getInstance().nextId() + ossTokenReqDTO.getSuffixName());
return map;
}
只要符合这个格式即可 https://bucket-name.oss-cn-chengdu.aliyuncs.com
IdGenerater.getInstance().nextId() 随便一个id作为文件名 不重复就行
ossFileUploadUrl(null), oss上传路径名 相对路径 随便啥都行, 我这里是业务代码
则为: host+/+filePath 直接访问即可 public的
看看控制台里是否有这个文件吧, 让前端自己找一找吧
下篇更精彩: STS认证方式(分片上传等, 需要配置权限)
前端代码(仅供参考): 前端将文件上传到OSS