一、阿里云OSS购买和配置?
参考资料 阿里云OSS操作官方文档
阿里云OSS购买和配置,阿里云oss购买和配置,也可以参考阿里云OSS官方文档。
二、SpringBoot整合OSS
2.1 pom
<dependencies>
<!-- commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!-- aliyun-oos -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<!-- apache-common-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2.2 yaml
server:
port: 8080
oss:
endpoint: oss-cn-hangzhou.aliyuncs.com
accessKeyId: LTAI5tNAxxxxxxAKwi3P
accessKeySecret: LVvhTbF0sKwNxxxxxxv5TsHeC8oz5R
bucketName: xxxxxx
packageName: files
urlPrefix: http://xxxxxx.oss-cn-hangzhou.aliyuncs.com/
2.3 配置类
2.3.1 OssConfig
@Data // lombok
@Configuration // 声明配置类,放入Spring容器
@ConfigurationProperties(prefix = "oss") //指定配置文件中自定义属性前缀
public class OssProperties {
@ApiModelProperty("外网访问节点")
private String endPoint;
@ApiModelProperty("点击阿里云头像accesskey管理获取")
private String accessKeyId;
@ApiModelProperty("点击阿里云头像accesskey管理获取")
private String accessKeySecret;
@ApiModelProperty("仓库名称")
private String bucketName;
@ApiModelProperty("上传成功后返回的url")
private String urlPrefix;
@ApiModelProperty("目标文件夹")
private String packageName;
@Bean // 将OSS 客户端交给Spring容器管理
public OSS OSSClient() {
return new OSSClient(endPoint, accessKeyId, accessKeySecret);
}
}
2.3.2 Swagger2Config
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket webApiConfig() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo webApiInfo() {
return new ApiInfoBuilder()
.title("SpringBoot整合OSS-API文档")
.description("阿里云OSS-文件上传下载测试")
.version("1.0")
.contact(new Contact("JAK的博客", "https://blog.csdn.net/qq_38826019", ""))
.build();
}
}
2.4 枚举类
public enum StatusCode {
SUCCESS("success", 200), ERROR("error", 500);
private String msg;
private Integer code;
StatusCode(String msg, Integer code) {
this.msg = msg;
this.code = code;
}
StatusCode(Integer code) {
this.code = code;
}
StatusCode(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
2.5 Service层
在service使用ossClient操作阿里云OSS,进行上传、下载、删除、查看所有文件等操作,同时可以将图片的url进行入库操作:
public interface FileUploadService {
/**
* 文件上传
*
* @param multipartFile 文件
* @return String
*/
String upload(MultipartFile multipartFile);
/**
* 文件下载
*
* @param fileName 文件名称
* @param response 响应
* @return String
*/
String download(String fileName, HttpServletResponse response) throws UnsupportedEncodingException;
/**
* 文件删除
*
* @param fileName 文件名称
* @return String
*/
String delete(String fileName);
}
@Service("fileUploadService")
public class FileUploadServiceImpl implements FileUploadService {
// 允许上传文件(图片)的格式
private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg", ".jpeg", ".gif", ".png"};
// 注入阿里云oss文件服务器客户端
@Autowired
private OSS ossClient;
// 注入案例与OSS基本配置类
@Autowired
private OssProperties ossProperties;
/**
* 文件上传
*
* @param uploadFile 文件
* @return 返回文件上传后的图片返回地址
*/
@Override
public String upload(MultipartFile uploadFile) {
// 获取oss的bucket名称
String bucketName = ossProperties.getBucketName();
// 获取oss目标文件夹
String packageName = ossProperties.getPackageName();
// 返回图片上传后返回的前缀url
String urlPrefix = ossProperties.getUrlPrefix();
// 校验图片格式
boolean isLegal = false;
for (String type : IMAGE_TYPE) {
if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
isLegal = true;
break;
}
}
// 如果图片格式不合法
if (!isLegal) {
return StatusCode.ERROR.getMsg();
}
// 获取文件原名称
String originalFilename = uploadFile.getOriginalFilename();
// 获取文件类型
String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
// 新文件名称
String newFileName = UUID.randomUUID().toString() + fileType;
// 构建日期路径,例如:OSS目标文件夹/2021/09/16/文件名
String filePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
// 文件上传的路径地址
String uploadImgUrl = packageName + "/" + filePath + "/" + newFileName;
// 获取文件输入流
InputStream inputStream = null;
try {
inputStream = uploadFile.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
/**
* 下面两行代码是重点坑:
* 现在阿里云OSS 默认图片上传ContentType是image/jpeg
* 也就是说,获取图片链接后,图片是下载链接,而并非在线浏览链接,
* 因此,这里在上传的时候要解决ContentType的问题,将其改为image/jpg
*/
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/jpg");
// 文件上传至阿里云OSS
ossClient.putObject(bucketName, uploadImgUrl, inputStream, metadata);
// 获取文件上传后的图片返回地址
String returnImgUrl = urlPrefix + uploadImgUrl;
return returnImgUrl;
}
/**
* 文件下载
*
* @param fileName 文件名称
* @param response 响应
* @return 文件下载响应状态
*/
@Override
public String download(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
// 文件名以附件的形式下载
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 获取oss的bucket名称
String bucketName = ossProperties.getBucketName();
// 获取oss目标文件夹
String packageName = ossProperties.getPackageName();
// 日期目录
// 注意,这里虽然写成这种固定获取日期目录的形式,逻辑上确实存在问题,但是实际上,filePath的日期目录应该是从数据库查询的
String filePath = new DateTime().toString("yyyy/MM/dd");
String fileKey = packageName + "/" + filePath + "/" + fileName;
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流
OSSObject ossObject = ossClient.getObject(bucketName, fileKey);
try {
// 读取文件内容
InputStream inputStream = ossObject.getObjectContent();
// 把输入流放入缓冲流
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
ServletOutputStream outputStream = response.getOutputStream();
// 把输出流放入缓冲流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
byte[] buffer = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, len);
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
bufferedInputStream.close();
return StatusCode.SUCCESS.getMsg();
} catch (IOException e) {
return StatusCode.ERROR.getMsg();
}
}
/**
* 文件删除
* 注意:在实际项目中,不需要删除OSS文件服务器中的文件,只需要删除数据库存储的文件路径即可!
*
* @param fileName 文件名称
* @return 文件删除响应状态
*/
@Override
public String delete(String fileName) {
// 获取oss的bucket名称
String bucketName = ossProperties.getBucketName();
// 获取oss的地域节点
String endPoint = ossProperties.getEndPoint();
// 获取oss的accessKeyId
String accessKeyId = ossProperties.getAccessKeyId();
// 获取oss目标文件夹
String packageName = ossProperties.getPackageName();
// 获取oss的accessKeySecret
String accessKeySecret = ossProperties.getAccessKeySecret();
// 日期目录,注意,这里虽然写成这种固定获取日期目录的形式,逻辑上确实存在问题,但是实际上,filePath的日期目录应该是从数据库查询的
String filePath = new DateTime().toString("yyyy/MM/dd");
try {
// 建议在方法中创建OSSClient 而不是使用@Bean注入,不然容易出现Connection pool shut down
OSSClient ossClient = new OSSClient(endPoint, accessKeyId, accessKeySecret);
// 根据BucketName,filetName删除文件
// 删除目录中的文件,如果是最后一个文件fileoath目录会被删除。
String fileKey = packageName + "/" + filePath + "/" + fileName;
ossClient.deleteObject(bucketName, fileKey);
try {
} finally {
ossClient.shutdown();
}
System.out.println("文件删除成功!");
return StatusCode.SUCCESS.getMsg();
} catch (Exception e) {
System.out.println("文件删除失败!");
e.printStackTrace();
return StatusCode.ERROR.getMsg();
}
}
}
2.6 Controller层
Controller提供测试接口
@Api("阿里云OSS文件上传、下载、删除API")
@RequestMapping("api/file/oss")
@RestController
public class OssFileController {
@Autowired
private FileUploadService fileUploadService;
@ApiOperation("文件上传")
@PostMapping("upload")
public JSONObject upload(@RequestParam("file") MultipartFile file) {
JSONObject jsonObject = new JSONObject();
if (file != null) {
String returnFileUrl = fileUploadService.upload(file);
if (returnFileUrl.equals("error")) {
jsonObject.put("error", "文件上传失败!");
return jsonObject;
}
jsonObject.put("success", "文件上传成功!");
jsonObject.put("returnFileUrl", returnFileUrl);
} else {
jsonObject.put("error", "文件上传失败!");
}
return jsonObject;
}
@ApiOperation("文件下载")
@GetMapping("download/{fileName}")
public JSONObject download(@PathVariable("fileName") String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
JSONObject jsonObject = new JSONObject();
String status = fileUploadService.download(fileName, response);
if (status.equals("error")) {
jsonObject.put("error", "文件下载失败!");
} else {
jsonObject.put("success", "文件下载成功!");
}
return jsonObject;
}
@ApiOperation("文件删除")
@GetMapping("/delete/{fileName}")
public JSONObject deleteFile(@PathVariable("fileName") String fileName) {
JSONObject jsonObject = new JSONObject();
String status = fileUploadService.delete(fileName);
if (status.equals("error")) {
jsonObject.put("error", "文件删除失败!");
} else {
jsonObject.put("success", "文件删除成功!");
}
return jsonObject;
}
}
2.7 Oss工具类
/**
* 视频教程
* https://www.bilibili.com/video/BV1x7411s7yu?from=search&seid=5547833394705458416&spm_id_from=333.337.0.0
*
* @author Jiang Akang
* employeeId: BG435424
* @date 2021/9/16
**/
public class OssUtil {
// 外网访问节点
private static final String ENDPOINT = "oss-cn-hangzhou.aliyuncs.com";
// 点击阿里云头像accesskey管理获取
private static final String ACCESSKEYID = "LTAI5tNABxxxxxxLAKwi3P";
// 点击阿里云头像accesskey管理获取
private static final String ACCESSKEYSECRET = "LVvhTbF0sKwNxxxxxx5TsHeC8oz5R";
// 仓库名称
private static final String BUKETNAME = "xxxxxx";
// 上传成功后返回的url
private static final String SUFFER_URL = "http://xxxxxx.oss-cn-hangzhou.aliyuncs.com/";
// 格式化日期
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
public OSSClient getOSSClient() {
// 创建一个OSSClient对象
OSSClient ossClient = new OSSClient(ENDPOINT, ACCESSKEYID, ACCESSKEYSECRET);
// 判断仓库是否存在
if (ossClient.doesBucketExist(BUKETNAME)) {
System.out.println("bucket创建成功");
} else {
// 通过api接口形式创建bucket仓库
System.out.println("bucket不存在,创建bucket: " + BUKETNAME);
// 创建一个oss的仓库
CreateBucketRequest bucketRequest = new CreateBucketRequest(null);
// 设置仓库名称
bucketRequest.setBucketName(BUKETNAME);
// 设置权限为公共读
bucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
ossClient.createBucket(bucketRequest);
ossClient.shutdown();
}
return ossClient;
}
public String uploadDocument(MultipartFile multipartFile, String businessType) {
// 获取oss连接
OSSClient ossClient = getOSSClient();
// 获取文件的后缀名称
String ext = Objects.requireNonNull(multipartFile.getOriginalFilename()).substring(multipartFile.getOriginalFilename().lastIndexOf("."));
// 上传至oss的哪个文件夹 通过filename 来指定 生成规则// www.baidu.com/img/20210916/test.jpg
String fileName = getFileName(businessType, ext);
String url = null;
// 通过ossClient来获取上传文件后返回的url
try {
ossClient.putObject(BUKETNAME, fileName, new ByteArrayInputStream(multipartFile.getBytes()));
url = SUFFER_URL + fileName;
System.out.println("上传资料成功,oss地址url: " + url);
} catch (IOException e) {
e.printStackTrace();
} finally {
ossClient.shutdown();
}
return url;
}
private String getFileName(String businessType, String ext) {
String date = sdf.format(new Date());
// 判断类型是否无值
if (StringUtils.isEmpty(businessType)) {
businessType = "default";
}
// 为了避免图片重名,使用UUID来命名图片
String uuid = UUID.randomUUID().toString().replace("-", "");
// 组合filename
String filename = businessType + "/" + date + "/" + uuid + ext;
return filename;
}
public static void main(String[] args) {
OssUtil ossUtil = new OssUtil();
ossUtil.getOSSClient();
}
}
三、Swagger测试API接口
本机访问:http://localhost:8080/swagger-ui.html#
?3.1 测试上传
?
?
3.2 测试下载
3.3 测试删除
?Gitee源码、参考博客、视频教程
|