oss文件上传 前端上传文件的优势,以及后端需要怎样配合

目录

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 到此 游戏结束了


1. 前言:

-> 1.1  前端上传优势: 

前端上传可以减少服务端压力,因为带宽是比较贵的。如果文件上传频率很高,很可能造成带宽不够,上传缓慢问题,影响用户体验。

2. 下面介绍一种普通上传方式: 

-> ps: 配合前端进行上传:

前端需要啥就给啥, 咱们不多想 整就完了 

-> 2.1 流程: 

前端请求后端获取一个token(有时效性),之后通过这个token来给阿里云鉴权,然后上传文件;这样将不会直接将accessKeyId和accessKeySecret直接暴露给用户了, js是不安全的

 -> 2.2 查看微信小程序官方文档

 -> 2.2.1 微信小程序官网位置

链接跳转:   如何在微信小程序环境下将文件上传到OSS_对象存储-阿里云

---> 2.2.2  看看前端都需要什么参数

参数 是否必选 说明
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

-> 2.3 后端目标明确,开整

 3. 具体实现

-> 3.1 entity实体类参数

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;

}

-> 3.2 controller 控制层

我这里不推荐使用是 因为前端还没准备好  嘿嘿

ResultResponse 随便啥, 返回值的类型, 写String都行,  这里就不提供了

    @Deprecated
    @ApiOperation("测试版... 前端oss 返回需要的秘钥")//暂不推荐使用
    @RequestMapping(value = "/getGenerateToken", method = RequestMethod.POST)
    public ResultResponse getGenerateToken(@RequestBody OssTokenReqDTO ossTokenReqDTO){

        log.info("===> 前端oss 返回需要的秘钥<===");

        return ossAddService.getGenerateToken(ossTokenReqDTO);
    }

-> 3.3 service的 impl层  

 /**
     * 引入秘钥等 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校验 先 !!! 注释掉 !!! , 先不加密(下文再说) 链接!!!!!!!

 -> 3.4 OssUtils封装方法

创建文件 加上注解@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;
    }

ps: host位置特别注意一下: 

只要符合这个格式即可 https://bucket-name.oss-cn-chengdu.aliyuncs.com

IdGenerater.getInstance().nextId() 随便一个id作为文件名 不重复就行

ossFileUploadUrl(null), oss上传路径名 相对路径 随便啥都行, 我这里是业务代码


4. 回调的url是什么???

-> 4.1 回调url 则是 前端上传后路径, 后台给返回的呦~~~

则为: host+/+filePath  直接访问即可 public的

->4.2  什么什么, 不能访问 报错了???

 看看控制台里是否有这个文件吧, 让前端自己找一找吧

-> 4.3 到此 游戏结束了

下篇更精彩:  STS认证方式(分片上传等, 需要配置权限)

前端代码(仅供参考): 前端将文件上传到OSS

你可能感兴趣的:(#,第三方服务,java,spring,oss,spring,boot,maven)