OSS前后端分离式上传文件,OSS前端直传 |
您所在的位置:网站首页 › 微信可以借钱吗怎么借5000元 › OSS前后端分离式上传文件,OSS前端直传 |
背景
以前我们一直采用: 后端转传 的方式进行文件上传 发现效率很低 且 后端服务器压力较大 现在我们优化成: 前端直传 后端提供token令牌 前端拿到令牌直接访问OSS上传文件效率提高了 且服务器压力也小了 准备工作1:登录阿里云控制台创建RAM用户
准备工作完毕 建个Spring Boot项目引入依赖 com.aliyun.oss aliyun-sdk-oss 3.10.2 javax.xml.bind jaxb-api 2.3.1 javax.activation activation 1.1.1 org.glassfish.jaxb jaxb-runtime 2.3.3 写个接口应该难不倒你 @RestController @RequestMapping("/manager/auth") public class AuthController { @Autowired private OssService ossService; @GetMapping(value = "/oss/token") //这里的R是我自己封装的统一返回对象 你也可以直接返回JSON啥的 public R ossToken() { return R.data(ossService.token()); } } # 文件上传 OSS: # 区域 endpoint: "https://oss-cn-xxxxx.aliyuncs.com" # 密钥 accessKeyId: "xxxxxxxxxxxxxxxxxxxxxxxx" accessKeySecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # roleArn roleArn: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 桶 bucketName: "xxxxxxxxx" regionId: "cn-shanghai" version: "2015-04-01" @Data @Configuration public class OSSParam { @Value("${OSS.endpoint}") private String endpoint; @Value("${OSS.accessKeyId}") private String accessKeyId; @Value("${OSS.accessKeySecret}") private String accessKeySecret; @Value("${OSS.roleArn}") private String roleArn; @Value("${OSS.bucketName}") private String bucketName; @Value("${OSS.regionId}") private String regionId; @Value("${OSS.version}") private String version; } public interface OssService { /** * 获取上传文件的token * @return */ AssumeRoleResponse token(); /** * 批量获取图片连接 * * @param filePathList * @return */ Map getUrlBatch(Collection filePathList); } @Service public class OssServiceImpl implements OssService { /** * 自定义的配置参数的类 */ @Autowired private OSSParam ossParam; @Override public AssumeRoleResponse token() { //随便写 参考下列格式即可 不要有特殊符号 String roleSessionName = "session_1001"; //执行角色授权 IClientProfile profile = DefaultProfile.getProfile( //cn-hangzhou 或者 cn-beijing 或者 cn-shanghai 这几个节点都可以 其他的好像不行 ossParam.getRegionId(), //开通账号时下发的两个参数 ossParam.getAccessKeyId(), ossParam.getAccessKeySecret() ); DefaultAcsClient client = new DefaultAcsClient(profile); final AssumeRoleRequest request = new AssumeRoleRequest(); //version 这里是固定的 2015-04-01 request.setVersion(ossParam.getVersion()); //开通角色时 角色信息里的 arn 属性 request.setRoleArn(ossParam.getRoleArn()); request.setRoleSessionName(roleSessionName); //临时授权有效时间,从 900 到 3600 秒 测试的时候建议写时间给长一点,免得报错都不知道为啥 request.setDurationSeconds(900L); try { final AssumeRoleResponse response = client.getAcsResponse(request); return response; } catch (ClientException e) { e.printStackTrace(); return null; } } /** * 文件临时访问 URL 获取 * * @param filePathList 后端存储的文件路径 * 例如 : web/img/abc.jpg * 其实就是你存储桶里面的文件夹路径 * 注意最前面不要带斜杠 例如这样 /web/img/abc.jpg 不要问我为什么 自己去试试就知道了 * @return 文件夹链接的 key : value 集合 调用方可以直接通过 map.get(filePath) 直接获取对应的链接 */ @Override public Map getUrlBatch(Collection filePathList) { //这里 等于 Map resultMap = new HashMap(); 只是我引用了工具包看起来舒服一点 Map resultMap = Maps.newHashMap(); if (CollectionUtils.isEmpty(filePathList)) { return resultMap; } //这个token可以用redis存起来过期了再重新生成,效率会高一点 //过期时间保持一致 或者redis缓存时间稍微短一点,错开那种刚好过期的时间点就好了 //比如 token 900秒(15分钟)到期,你就设置redis的key 720秒(12分钟)到期,完美错开 AssumeRoleResponse token = token(); // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build( params.getStsEndpoint(), token.getCredentials().getAccessKeyId(), token.getCredentials().getAccessKeySecret(), token.getCredentials().getSecurityToken() ); //过期时间尽量短一点 1-3 分钟即可, //只要前端能够显示出来就行了 (时间太长,可能会被人恶意访问造成流量泄露,产生大量费用。切记!!!!) //以前小白的时候直接生成10年有效的链接。。。现在看起来是真的虎 Long expirationTime = System.currentTimeMillis() + params.getStsEffectiveTime(); Date expirationDate = new Date(expirationTime); filePathList.forEach(filePath -> { //生成GET请求链接 URL url = ossClient.generatePresignedUrl(params.getStsBucketName(), filePath, expirationDate); resultMap.put(filePath, url.toString()); }); return resultMap; } } 用postman点一下看看
本人是个写后端的 前端没怎么学,但只需要知道大概原理即可 首先去GitHub 下载两个 sdk 文件 好了!试试看,选一个文件,就把这个js文件传上去看看 好了赶紧去点赞收藏吧 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |