OSS
pom依赖
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.54</version>
</dependency>
设计思路
创建Service包,添加OSSService接口,包含upload方法,
package com.izyq.oss.service;
import org.springframework.web.multipart.MultipartFile;
public interface OSSService {
String upload(MultipartFile file);
}
创建Impl包,添加OSSServiceIml实现
其中ossClient
为自定义的工具类,实现与OSS的连接,返回一个COSClient
对象。
下面的代码参考官方文档 流类型( InputStream 类型)上传,使用的是简单上传,没有使用高级接口。
调用高级接口可以再写一个工具类。
package com.izyq.oss.service.Impl;
import com.izyq.oss.service.OSSService;
import com.izyq.oss.utils.ConstantYML;
import com.izyq.oss.utils.ossClient;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
@Component
public class OSSServiceImpl implements OSSService {
@Override
public String upload(MultipartFile file) {
// 调用 COS 接口之前必须保证本进程存在一个 COSClient 实例,如果没有则创建
COSClient cosClient = ossClient.getClient();
// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式
String bucketName = ConstantYML.BUCKET_NAME ;
//构建日期路径:avatar/2019/02/26/文件名
String filePath = new DateTime().toString("yyyy/MM/dd");
// 对象键(Key)是对象在存储桶中的唯一标识。
String key = filePath + "/" + file.getOriginalFilename();
//获取上传文件流
InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
ObjectMetadata objectMetadata = new ObjectMetadata();
// 上传的流如果能够获取准确的流长度,则推荐一定填写 content-length
// 如果确实没办法获取到,则下面这行可以省略,但同时高级接口也没办法使用分块上传了
objectMetadata.setContentLength(file.getSize());
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, objectMetadata);
try {
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
System.out.println(putObjectResult.getRequestId());
} catch (CosServiceException e) {
e.printStackTrace();
} catch (CosClientException e) {
e.printStackTrace();
}
// 确认本进程不再使用 cosClient 实例之后,关闭之
cosClient.shutdown();
return key;
}
}
在utils包中创建工具类ossClient
此处注入了application.yml里的配置,通过工具类的ConstantYML实现
package com.izyq.oss.utils;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.region.Region;
/**
* Generate request client tool class
*/
public class ossClient {
public static COSClient getClient() {
// 1 初始化用户身份信息(secretId, secretKey)。
String secretId = ConstantYML.SECRET_ID;
String secretKey = ConstantYML.SECRET_KEY;
return getCosClient(secretId,secretKey, ConstantYML.REGION_NAME);
}
public static COSClient getCosClient(String secretId, String secretKey, String _region) {
// 1 初始化用户身份信息(secretId, secretKey)。
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置 bucket 的区域, CI 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
// clientConfig 中包含了设置 region, https(默认 https), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
Region region = new Region(_region);
ClientConfig clientConfig = new ClientConfig(region);
clientConfig.setHttpProtocol(HttpProtocol.http);
// 3 生成 cos 客户端。
return new COSClient(cred, clientConfig);
}
}
工具类ConstantYML
优雅的获取yml的配置信息
使用了@ConfigurationProperties和InitializingBean接口
package com.izyq.oss.utils;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "tencent.oss")
public class ConstantYML implements InitializingBean {
private String accessKey;
private String secretKey;
private String regionName;
private String bucketName;
public static String SECRET_ID;
public static String SECRET_KEY;
public static String REGION_NAME;
public static String BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception {
SECRET_ID = accessKey;
SECRET_KEY = secretKey;
REGION_NAME = regionName;
BUCKET_NAME = bucketName;
}
}
最后在Controller包里面实现OSSController
package com.izyq.oss.controller;
import com.izyq.common.utils.R;
import com.izyq.oss.service.OSSService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Api("腾讯云OSS")
@CrossOrigin
@RestController
@RequestMapping("oss")
public class OSSController {
@Autowired
private OSSService ossService;
@ApiOperation(value = "文件上传")
@PostMapping("upload")
@ApiImplicitParam(name = "file",value = "单文件上传",required = true,dataType="MultipartFile",
allowMultiple = true,paramType = "form")
public R upload(
@RequestPart("file") MultipartFile file) {
String key = ossService.upload(file);
String uploadUrl = "https://glxy-1304079174.cos.ap-chongqing.myqcloud.com/" + key;
return R.ok().message("文件上传成功").data("url", uploadUrl);
}
}
遇到的问题
Knife4j 3.0.3文件上传不显示上传选择文本域
解决
注意 paramType= "form"
@ApiImplicitParam(name = "file",value = "单文件上传",required = true,dataType="MultipartFile",
allowMultiple = true,paramType = "form")
@PostMapping("/analysisGps")
public AjaxResult analysisGps(@RequestPart("file") MultipartFile file) {
}
OSS上传文件大小限制
Spring Boot修改最大上传文件限制:The field file exceeds its maximum permitted size of 1048576 bytes.SpringBoot做文件上传时出现了The field file exceeds its maximum permitted size of 1048576 bytes.错误,显示文件的大小超出了允许的范围。查看了官方文档,原来Spring Boot工程嵌入的tomcat限制了请求的文件大小,这一点在Spring Boot的官方文档中有说明.
解决
spring.servlet.multipart.max-file-size=5GB
spring.servlet.multipart.max-request-size=5GB