使用阿里云的OSS保存图片
简单说一下这个OSS干啥用的,我们知道mysql这种关系型数据库最好不要存长文本还有二进制数据,比如图片,文件等,那么这些文件和图片放哪里呢?
本篇说的就是放到阿里云的OSS中去,然后数据库中只存放对应的url,我们只需要拿着这个url就可以访问到我们需要的资源;例如用户头像,还有需要商品的图片等等;
1.首先到阿里云中进入到OSS中,然后去创建一个Bucket,下面这样:
只用修改下面三个,其他的都是默认就行,注意这个bucket的名字很重要,后面在java代码中需要配置:
2.然后进入到创建的bucket中,找到这个endpoint复制下来,后面会用到;
3.找到你阿里云自己的id和密钥复制下来,后面会用到:
4.新建一个springboot项目,并且常用的依赖(包括使用lombok和swagger)和OSS依赖,并且在properties配置文件中配置前面前3步复制下来的东西:
<!-- 阿里云oss依赖 --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> </dependency> <!-- 日期工具栏依赖 --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> </dependency>
aliyun.oss.file.bucketname=你的bucket的名字 aliyun.oss.file.endpoint=你的endpoint路径 aliyun.oss.file.keyid=你的阿里云的id aliyun.oss.file.keysecret=你的阿里云的密钥
5.使用一个类和上面properties文件中的属性绑定起来,方便我们使用:
package com.protagonist.utils; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Getter @Setter @Component @ConfigurationProperties(prefix = "aliyun.oss.file") public class ConstantPropertiesUtils{ private String endpoint; private String keyid; private String keysecret; private String bucketname; }
6.controller代码,返回保存在OSS中文件的全路径,这个Result 就是一个对前端统一的类型,也可以直接返回HashMap
package com.protagonist.controller; import com.protagonist.responseVO.Result; import com.protagonist.responseVO.StatusCode; import com.protagonist.service.OssService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.util.HashMap; @Api("文件上传") @RestController @RequestMapping("/eduoss") @CrossOrigin public class OssController { @Resource private OssService ossService; //上传头像的方法 @PostMapping("/fileOss") @ApiOperation(value = "文件上传") public Result UploadOssFile(MultipartFile file) { String url = ossService.uploadFileAvatar(file); HashMap<String, String> map = new HashMap<>(); map.put("url",url); return new Result<>(true, StatusCode.OK,"上传成功",map); } }
7.service代码,只需要修改那个自定义异常还有状态码,其他的不需要改:
package com.protagonist.service; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.protagonist.responseVO.StatusCode; import com.protagonist.servicebase.exception.ProtagonistException; import com.protagonist.utils.ConstantPropertiesUtils; import lombok.extern.slf4j.Slf4j; import org.joda.time.DateTime; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.InputStream; import java.util.UUID; @Service @Slf4j public class OssService{ @Resource private ConstantPropertiesUtils constantPropertiesUtils; public String uploadFileAvatar(MultipartFile file) { //获取oss上传配置文件中的参数 String bucketName = constantPropertiesUtils.getBucketname(); String endpoint = constantPropertiesUtils.getEndpoint(); String keyId = constantPropertiesUtils.getKeyid(); String keySecret = constantPropertiesUtils.getKeysecret(); OSS ossClient; InputStream inputStream; try { // 创建OSSClient实例。 ossClient = new OSSClientBuilder().build(endpoint, keyId, keySecret); // 上传文件流 inputStream = file.getInputStream(); //为了使得文件可以重复上传,每次上传的时候需要将文件名进行修改 String fileName = file.getOriginalFilename(); log.info("图片上传的名字为:{}",fileName); String uuid = UUID.randomUUID().toString().replaceAll("-", ""); String newFileName = uuid + fileName; //获取当前日期,然后以日期和新的文件名组成全路径,使得oss中的文件按照日期进行分类存储 String date = new DateTime().toString("yyyy/MM/dd"); String fullFileName = date + "/" + newFileName; log.info("图片保存在oss的全路径为:{}",fullFileName); //第一个参数Bucket名称 第二个参数 上传到oss文件路径和文件名称 ossClient.putObject(bucketName, fullFileName, inputStream); // 关闭OSSClient。 ossClient.shutdown(); return "https://"+bucketName+"."+ endpoint+"/"+fullFileName; } catch (Exception e) { log.error("文件上传失败",e); throw new ProtagonistException(StatusCode.REMOTEERROR,"文件上传oss失败"); } } }
8.测试,图片上传成功,返回OSS中保存的url,然后前端就可以直接拿到这个url做些花里胡哨的事!
我们可以看看OSS中保存的图片;
其实这种图片还有文件啥的,也可以自己自己搭建一个文件服务器丢到里面去,简单一点的使用docker,有兴趣的可以试试!