文件策略接口
/**
* 文件策略接口
*/
public interface FileStrategy {
/**
* 文件上传
*
* @param file 文件
* @param bucket 桶
* @param bizType 业务类型
* @return 文件对象
*/
File upload(MultipartFile file, String bucket, String bizType);
/**
* 删除源文件
*
* @param fileDeleteBO 待删除文件
* @return 是否成功
*/
boolean delete(FileDeleteBO fileDeleteBO);
}
多种实现类
文件抽象策略 处理类
/**
* 文件抽象策略 处理类
*
*/
@Slf4j
@RequiredArgsConstructor
public abstract class AbstractFileStrategy implements FileStrategy {
// public static final String CF_ACCOUNT_ID = "842c4ed8bb33981a8b1c6ee70557a796";
String CF_ACCOUNT_ID;
public static final String CF_BASE_URL = "https://api.cloudflare.com/client/v4/accounts/";
private static final String FILE_SPLIT = ".";
protected final FileServerProperties fileProperties;
protected final FileMapper fileMapper;
/**
* 上传文件
*
* @param multipartFile 文件
* @return 附件
*/
@Override
public File upload(MultipartFile multipartFile, String bucket, String bizType) {
try {
if (!StrUtil.contains(multipartFile.getOriginalFilename(), FILE_SPLIT)) {
throw BizException.wrap(BASE_VALID_PARAM.build("文件缺少后缀名"));
}
File file = File.builder()
.originalFileName(multipartFile.getOriginalFilename())
.contentType(multipartFile.getContentType())
.size(multipartFile.getSize())
.bizType(bizType)
.suffix(FilenameUtils.getExtension(multipartFile.getOriginalFilename()))
.fileType(FileTypeUtil.getFileType(multipartFile.getContentType()))
.build();
if (multipartFile.getContentType().startsWith("vtt")) {
uploadVtt(file, multipartFile, bucket, bizType);
} else {
uploadFile(file, multipartFile, bucket);
}
return file;
} catch (Exception e) {
log.error("ex", e);
throw BizException.wrap(BASE_VALID_PARAM.build("文件上传失败"), e);
}
}
/**
* @param uid uid
* @param languageTag languageTag
* @throws Exception
*/
private void uploadVtt(File file, MultipartFile multipartFile, String uid, String languageTag) throws Exception {
String contentType = file.getContentType();
String url = CF_BASE_URL + CF_ACCOUNT_ID + "/stream/" + uid + "/" + languageTag;
OkHttpClient client = new OkHttpClient();
Request request = getRequest(multipartFile, contentType, url);
extracted(client, request);
final Call call = client.newCall(request);
try (Response response = call.execute();) {
assert response.body() != null;
String string = response.body().string();
CloudFlareResult<Map<String, Object>> cloudFlareResult = JSONObject.parseObject(string, new TypeReference<CloudFlareResult<Map<String, Object>>>() {
});
if (!cloudFlareResult.getSuccess()) {
throw new BizException("uploadFile fail");
}
// CloudFlareVideoResult result = cloudFlareResult.getResult();
// file.setUrl(result.getPlayback().getOrDefault("hls", "")).setUniqueFileName(result.getThumbnail());
} catch (Exception e) {
log.error("uploadFile fail:{}", e.getMessage(), e);
throw new BizException("uploadFile fail");
}
}
@NotNull
private static Request getRequest(MultipartFile multipartFile, String contentType, String url) throws IOException {
RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), multipartFile.getBytes());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", multipartFile.getName(), fileBody)
.build();
Request request = new Request.Builder().url(url).addHeader("Authorization", "Bearer KOs2DOm2w0_QvlYizgkVjso5HOQxnr-krRTfIVVd").post(requestBody).build();
return request;
}
private static void extracted(OkHttpClient client, Request request) {
client.newBuilder()
.connectTimeout(500, TimeUnit.SECONDS)
.readTimeout(500, TimeUnit.SECONDS)
.callTimeout(500, TimeUnit.SECONDS)
.writeTimeout(500, TimeUnit.SECONDS)
.build()
.newCall(request);
}
/**
* 具体类型执行上传操作
*
* @param file 附件
* @param multipartFile 文件
* @param bucket bucket
* @throws Exception 异常
*/
protected abstract void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception;
@Override
public String getUrl(FileGetUrlBO fileGet) {
return findUrl(Arrays.asList(fileGet)).get(fileGet.getPath());
}
/**
* 获取年月日 2020/09/01
*
* @return
*/
protected String getDateFolder() {
return LocalDate.now().format(DateTimeFormatter.ofPattern(SLASH_DATE_FORMAT));
}
/**
* 企业/年/月/日/业务类型/唯一文件名
*/
protected String getPath(String bizType, String uniqueFileName) {
return new StringJoiner(StrPool.SLASH).add(String.valueOf(ContextUtil.getTenant()))
.add(bizType).add(getDateFolder()).add(uniqueFileName).toString();
}
protected String getUniqueFileName(File file) {
return new StringJoiner(StrPool.DOT)
.add(UUID.randomUUID().toString().replace("-", ""))
.add(file.getSuffix()).toString();
}
}
HUAWEI_OSS 文件上传的实现
@Slf4j
@Component("HUAWEI_OSS")
public class HuaweiFileStrategyImpl extends AbstractFileStrategy {
private static OkHttpClient httpClient = new OkHttpClient.Builder().followRedirects(false)
.retryOnConnectionFailure(false).cache(null).build();
public HuaweiFileStrategyImpl(FileServerProperties fileProperties, FileMapper fileMapper) {
super(fileProperties, fileMapper);
}
private static Request.Builder getBuilder(TemporarySignatureResponse res) {
Request.Builder builder = new Request.Builder();
for (Map.Entry<String, String> entry : res.getActualSignedRequestHeaders().entrySet()) {
builder.header(entry.getKey(), entry.getValue());
}
return builder.url(res.getSignedUrl());
}
private static String getResponse(Request request) throws IOException {
Call c = httpClient.newCall(request);
Response res = c.execute();
if (res.body() != null) {
String content = res.body().string();
return content;
}
res.close();
return StrPool.EMPTY;
}
@Override
protected void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception {
FileServerProperties.Huawei huawei = fileProperties.getHuawei();
//生成文件名
String uniqueFileName = getUniqueFileName(file);
String path = getPath(file.getBizType(), uniqueFileName);
bucket = StrUtil.isEmpty(bucket) ? huawei.getBucket() : bucket;
try (ObsClient obsClient = new ObsClient(huawei.getAccessKey(), huawei.getSecretKey(), huawei.getEndpoint())) {
// createBucket(obsClient, bucket);
PutObjectRequest request = new PutObjectRequest(bucket, path, multipartFile.getInputStream());
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(multipartFile.getContentType());
metadata.setContentDisposition("attachment;fileName=" + URLUtil.encode(file.getOriginalFileName()));
request.setMetadata(metadata);
obsClient.putObject(request);
String url = huawei.getUrlPrefix() + bucket + StrPool.SLASH + path;
file.setUrl(url);
}
file.setBucket(bucket);
file.setPath(path);
file.setUniqueFileName(uniqueFileName);
file.setStorageType(FileStorageType.HUAWEI_OSS);
}
private void createBucket(ObsClient obsClient, String bucket) throws ObsException {
boolean exists = obsClient.headBucket(bucket);
if (!exists) {
ObsBucket obsBucket = new ObsBucket();
obsBucket.setBucketName(bucket);
obsBucket.setLocation(fileProperties.getHuawei().getLocation());
// // 设置桶访问权限为公共读,默认是私有读写
// obsBucket.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
obsClient.createBucket(obsBucket);
}
}
@Override
@SneakyThrows
public boolean delete(FileDeleteBO file) {
FileServerProperties.Huawei huawei = fileProperties.getHuawei();
try (ObsClient obsClient = new ObsClient(huawei.getAccessKey(), huawei.getSecretKey(),
huawei.getEndpoint())) {
obsClient.deleteObject(file.getBucket(), file.getPath());
}
return true;
}
@Override
@SneakyThrows
public Map<String, String> findUrl(List<FileGetUrlBO> fileGets) {
FileServerProperties.Huawei huawei = fileProperties.getHuawei();
Set<String> publicBucket = fileProperties.getPublicBucket();
Map<String, String> map = new LinkedHashMap<>(CollHelper.initialCapacity(fileGets.size()));
try (ObsClient obsClient = new ObsClient(huawei.getAccessKey(), huawei.getSecretKey(),
huawei.getEndpoint())) {
for (FileGetUrlBO fileGet : fileGets) {
String bucket = StrUtil.isEmpty(fileGet.getBucket()) ? huawei.getBucket() : fileGet.getBucket();
try {
if (CollUtil.isNotEmpty(publicBucket) && publicBucket.contains(bucket)) {
StringBuilder url = new StringBuilder(huawei.getUrlPrefix())
.append(fileGet.getBucket())
.append(StrPool.SLASH)
.append(fileGet.getPath());
map.put(fileGet.getPath(), url.toString());
} else {
TemporarySignatureRequest req = new TemporarySignatureRequest(HttpMethodEnum.GET, 300);
req.setBucketName(fileGet.getBucket());
req.setObjectKey(fileGet.getPath());
req.setExpires(huawei.getExpiry());
TemporarySignatureResponse res = obsClient.createTemporarySignature(req);
map.put(fileGet.getPath(), res.getSignedUrl());
}
} catch (Exception e) {
log.warn("加载文件url地址失败,请确保yml中第三方存储参数配置正确. bucket={}, , 文件名={} path={}", bucket, fileGet.getOriginalFileName(), fileGet.getPath(), e);
map.put(fileGet.getPath(), StrPool.EMPTY);
}
}
}
return map;
}
}
ALI_OSS的文件上传实现
@Slf4j
@Component("ALI_OSS")
public class AliFileStrategyImpl extends AbstractFileStrategy {
public AliFileStrategyImpl(FileServerProperties fileProperties, FileMapper fileMapper) {
super(fileProperties, fileMapper);
}
@Override
protected void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception {
FileServerProperties.Ali ali = fileProperties.getAli();
OSS ossClient = new OSSClientBuilder().build(ali.getEndpoint(), ali.getAccessKeyId(),
ali.getAccessKeySecret());
if (StrUtil.isEmpty(bucket)) {
bucket = ali.getBucket();
}
if (!ossClient.doesBucketExist(bucket)) {
ossClient.createBucket(bucket);
}
//生成文件名
String uniqueFileName = getUniqueFileName(file);
// 企业id/功能点/年/月/日/file
String path = getPath(file.getBizType(), uniqueFileName);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentDisposition("attachment;fileName=" + file.getOriginalFileName());
metadata.setContentType(file.getContentType());
PutObjectRequest request = new PutObjectRequest(bucket, path, multipartFile.getInputStream(), metadata);
PutObjectResult result = ossClient.putObject(request);
log.info("result={}", JsonUtil.toJson(result));
String url = ali.getUrlPrefix() + bucket + StrPool.SLASH + path;
file.setUrl(url);
file.setUniqueFileName(uniqueFileName);
file.setBucket(bucket);
file.setPath(path);
file.setStorageType(FileStorageType.ALI_OSS);
ossClient.shutdown();
}
@Override
public boolean delete(FileDeleteBO file) {
FileServerProperties.Ali ali = fileProperties.getAli();
String bucketName = StrUtil.isEmpty(file.getBucket()) ? ali.getBucket() : file.getBucket();
OSS ossClient = new OSSClientBuilder().build(ali.getEndpoint(), ali.getAccessKeyId(), ali.getAccessKeySecret());
ossClient.deleteObject(bucketName, file.getPath());
ossClient.shutdown();
return true;
}
@Override
public Map<String, String> findUrl(List<FileGetUrlBO> fileGets) {
OSS ossClient = createOss();
Set<String> publicBucket = fileProperties.getPublicBucket();
FileServerProperties.Ali ali = fileProperties.getAli();
Map<String, String> map = new LinkedHashMap<>(CollHelper.initialCapacity(fileGets.size()));
for (FileGetUrlBO fileGet : fileGets) {
String bucket = StrUtil.isEmpty(fileGet.getBucket()) ? ali.getBucket() : fileGet.getBucket();
try {
if (CollUtil.isNotEmpty(publicBucket) && publicBucket.contains(bucket)) {
StringBuilder url = new StringBuilder(ali.getUrlPrefix())
.append(fileGet.getBucket())
.append(StrPool.SLASH)
.append(fileGet.getPath());
map.put(fileGet.getPath(), url.toString());
} else {
map.put(fileGet.getPath(), generatePresignedUrl(bucket, fileGet.getPath()));
}
} catch (Exception e) {
log.warn("加载文件url地址失败,请确保yml中第三方存储参数配置正确. bucket={}, , 文件名={} path={}", bucket, fileGet.getOriginalFileName(), fileGet.getPath(), e);
map.put(fileGet.getPath(), StrPool.EMPTY);
}
}
ossClient.shutdown();
return map;
}
/**
* 获取一个ossclient
*
* @return
*/
public OSS createOss() {
FileServerProperties.Ali ali = fileProperties.getAli();
String accessKeyId = ali.getAccessKeyId();
String accessKeySecret = ali.getAccessKeySecret();
String endPoint = ali.getEndpoint();
return new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
}
/**
* 获取有访问权限的路径地址
*
* @param bucketName
* @param key
* @return
*/
private String generatePresignedUrl(String bucketName, String key) {
FileServerProperties.Ali ali = fileProperties.getAli();
OSS oss = createOss();
Date date = new Date(System.currentTimeMillis() + ali.getExpiry());
URL url = oss.generatePresignedUrl(bucketName, key, date);
return url.toString();
}
}
CLOUD_FLARE实现文件上传
@Slf4j
@Component("CLOUD_FLARE")
public class CloudFlareStrategyImpl extends AbstractFileStrategy {
@Value("${cf.account.id}")
String CF_ACCOUNT_ID ;
@Value("${cf.account.token}")
String token ;
@Resource
private CloudFlareApi cloudFlareApi;
public CloudFlareStrategyImpl(FileServerProperties fileProperties, FileMapper fileMapper) {
super(fileProperties, fileMapper);
}
@Override
public boolean delete(FileDeleteBO fileDeleteBO) {
return false;
}
@Override
public Map<String, String> findUrl(List<FileGetUrlBO> fileGets) {
return null;
}
@Override
protected void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception {
String contentType = file.getContentType();
if (contentType.startsWith("video")) {
uploadVideo(file, multipartFile);
} else {
String url = CF_BASE_URL + CF_ACCOUNT_ID + "/images/v1";
OkHttpClient client = new OkHttpClient();
RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), multipartFile.getBytes());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", multipartFile.getName(), fileBody)
.build();
Request request = new Request.Builder().url(url).addHeader("Authorization", token).post(requestBody).build();
//请求超时时间5s
client.newBuilder().readTimeout(500, TimeUnit.SECONDS).build().newCall(request);
final Call call = client.newCall(request);
try (Response response = call.execute();) {
assert response.body() != null;
String string = response.body().string();
CloudFlareResult<CloudFlareImagesResult> cloudFlareResult = JSONObject.parseObject(string, new TypeReference<CloudFlareResult<CloudFlareImagesResult>>() {
});
CloudFlareImagesResult result = cloudFlareResult.getResult();
file.setUrl(result.getVariants().get(0)).setUniqueFileName(result.getId());
} catch (Exception e) {
log.error("uploadFile fail:{}", e.getMessage(), e);
throw new BizException("uploadFile fail");
}
}
}
private void uploadVideo(File file, MultipartFile multipartFile) throws Exception {
String contentType = file.getContentType();
String url = CF_BASE_URL + CF_ACCOUNT_ID + "/stream";
OkHttpClient client = new OkHttpClient();
RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), multipartFile.getBytes());
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", multipartFile.getName(), fileBody)
.build();
Request request = new Request.Builder().url(url).addHeader("Authorization", token).post(requestBody).build();
//请求超时时间5s
client.newBuilder()
.connectTimeout(500, TimeUnit.SECONDS)
.readTimeout(500, TimeUnit.SECONDS)
.callTimeout(500, TimeUnit.SECONDS)
.writeTimeout(500, TimeUnit.SECONDS)
.build()
.newCall(request);
final Call call = client.newCall(request);
try (Response response = call.execute();) {
assert response.body() != null;
String string = response.body().string();
CloudFlareResult<CloudFlareVideoResult> cloudFlareResult = JSONObject.parseObject(string, new TypeReference<CloudFlareResult<CloudFlareVideoResult>>() {
});
CloudFlareVideoResult result = cloudFlareResult.getResult();
file.setUrl(result.getPlayback().getOrDefault("hls", "")).setFileMd5(result.getUid()).setUniqueFileName(result.getThumbnail());
} catch (Exception e) {
log.error("uploadFile fail:{}", e.getMessage(), e);
throw new BizException("uploadFile fail");
}
}
}
QINIU_OSS的文件上传
@Component("QINIU_OSS")
public class QiNiuFileStrategyImpl extends AbstractFileStrategy {
private static StringMap PUT_POLICY = new StringMap();
static {
PUT_POLICY.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}");
}
private final UploadManager uploadManager;
private final BucketManager bucketManager;
private final Auth auth;
public QiNiuFileStrategyImpl(FileServerProperties fileProperties, FileMapper fileMapper,
UploadManager uploadManager, BucketManager bucketManager, Auth auth) {
super(fileProperties, fileMapper);
this.uploadManager = uploadManager;
this.bucketManager = bucketManager;
this.auth = auth;
}
/**
* 获取上传凭证
*
* @return
*/
private String getUploadToken(String bucket) {
FileServerProperties.QiNiu qiNiu = fileProperties.getQiNiu();
String token = this.auth.uploadToken(bucket, null, qiNiu.getExpiry(), PUT_POLICY);
log.info("token={}", token);
return token;
}
@Override
protected void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception {
FileServerProperties.QiNiu qiNiu = fileProperties.getQiNiu();
if (StrUtil.isEmpty(bucket)) {
bucket = qiNiu.getBucket();
}
//生成文件名
String uniqueFileName = getUniqueFileName(file);
// 企业id/功能点/年/月/日/file
String path = getPath(file.getBizType(), uniqueFileName);
StringMap params = new StringMap();
params.put("x-qn-meta-contentDisposition", "attachment;fileName=" + file.getOriginalFileName());
Response response = this.uploadManager.put(multipartFile.getInputStream(), path, getUploadToken(bucket),
params, file.getContentType());
log.info("response={}", JsonUtil.toJson(response));
if (response.statusCode == 200) {
DefaultPutRet defaultPutRet = JsonUtil.parse(response.bodyString(), DefaultPutRet.class);
log.info("defaultPutRet={}", JsonUtil.toJson(defaultPutRet));
file.setUniqueFileName(uniqueFileName);
file.setBucket(bucket);
file.setPath(path);
}
file.setUrl(qiNiu.getUrlPrefix() + bucket + StrPool.SLASH + path);
file.setStorageType(FileStorageType.QINIU_OSS);
}
@SneakyThrows
@Override
public boolean delete(FileDeleteBO file) {
FileServerProperties.QiNiu qiNiu = fileProperties.getQiNiu();
String bucket = StrUtil.isEmpty(file.getBucket()) ? qiNiu.getBucket() : file.getBucket();
Response response = bucketManager.delete(bucket, file.getPath());
log.info("response={}", JsonUtil.toJson(response));
return true;
}
@SneakyThrows
@Override
public Map<String, String> findUrl(List<FileGetUrlBO> fileGets) {
Map<String, String> map = new LinkedHashMap<>(CollHelper.initialCapacity(fileGets.size()));
FileServerProperties.QiNiu qiNiu = fileProperties.getQiNiu();
Set<String> publicBucket = fileProperties.getPublicBucket();
for (FileGetUrlBO fileGet : fileGets) {
String bucket = StrUtil.isEmpty(fileGet.getBucket()) ? qiNiu.getBucket() : fileGet.getBucket();
try {
if (CollUtil.isNotEmpty(publicBucket) && publicBucket.contains(bucket)) {
StringBuilder url = new StringBuilder(qiNiu.getUrlPrefix())
.append(fileGet.getBucket())
.append(StrPool.SLASH)
.append(fileGet.getPath());
map.put(fileGet.getPath(), url.toString());
} else {
DownloadUrl url = new DownloadUrl(qiNiu.getDomain(), false, fileGet.getPath());
url.setAttname(fileGet.getOriginalFileName());
long deadline = System.currentTimeMillis() / 1000 + qiNiu.getExpiry();
String urlString = url.buildURL(auth, deadline);
map.put(fileGet.getPath(), urlString);
}
} catch (Exception e) {
log.warn("加载文件url地址失败,请确保yml中第三方存储参数配置正确. bucket={}, , 文件名={} path={}", bucket, fileGet.getOriginalFileName(), fileGet.getPath(), e);
map.put(fileGet.getPath(), StrPool.EMPTY);
}
}
return map;
}
}
LOCAL文件上传
@Slf4j
@Component("LOCAL")
public class LocalFileStrategyImpl extends AbstractFileStrategy {
public LocalFileStrategyImpl(FileServerProperties fileProperties, FileMapper fileMapper) {
super(fileProperties, fileMapper);
}
@Override
protected void uploadFile(File file, MultipartFile multipartFile, String bucket) throws Exception {
FileServerProperties.Local local = fileProperties.getLocal();
bucket = StrUtil.isEmpty(bucket) ? local.getBucket() : bucket;
//生成文件名
String uniqueFileName = getUniqueFileName(file);
// 相对路径
String path = getPath(file.getBizType(), uniqueFileName);
// web服务器存放的绝对路径
String absolutePath = Paths.get(local.getStoragePath(), bucket, path).toString();
// 存储文件
java.io.File outFile = new java.io.File(absolutePath);
FileUtils.writeByteArrayToFile(outFile, multipartFile.getBytes());
// 返回数据
String url = local.getUrlPrefix() + bucket + StrPool.SLASH + path;
file.setUrl(url);
file.setUniqueFileName(uniqueFileName);
file.setPath(path);
file.setBucket(bucket);
file.setStorageType(FileStorageType.LOCAL);
}
@Override
public boolean delete(FileDeleteBO file) {
FileServerProperties.Local local = fileProperties.getLocal();
java.io.File ioFile = new java.io.File(Paths.get(local.getStoragePath(), file.getBucket(), file.getPath()).toString());
FileUtils.deleteQuietly(ioFile);
return true;
}
@Override
public Map<String, String> findUrl(List<FileGetUrlBO> fileGets) {
Map<String, String> map = new LinkedHashMap<>(CollHelper.initialCapacity(fileGets.size()));
// 方式1 取上传时存的url (多查询一次数据库)
// List<String> paths = fileGets.stream().map(FileGetUrlBO::getPath).collect(Collectors.toList());
// List<File> list = fileMapper.selectList(Wraps.<File>lbQ().eq(File::getPath, paths));
// list.forEach(item -> map.put(item.getPath(), item.getUrl()));
// 方式2 重新拼接 (urlPrefix 可能跟上传时不一样)
FileServerProperties.Local local = fileProperties.getLocal();
fileGets.forEach(item -> {
StringBuilder url = new StringBuilder(local.getUrlPrefix())
.append(item.getBucket())
.append(StrPool.SLASH)
.append(item.getPath());
map.put(item.getPath(), url.toString());
});
return map;
}
}
具体使用
controller
/**
* 上传文件
*/
@ApiOperation(value = "附件上传", notes = "附件上传")
@ApiImplicitParams({
@ApiImplicitParam(name = "file", value = "附件", dataType = DATA_TYPE_MULTIPART_FILE, allowMultiple = true, required = true),
})
@PostMapping(value = "/anyone/upload")
@SysLog("上传附件")
public R<FileResultVO> upload(@RequestParam(value = "file") MultipartFile file,
@Validated FileUploadVO attachmentVO) {
// 忽略路径字段,只处理文件类型
if (file.isEmpty()) {
return R.validFail(BASE_VALID_PARAM.build("请上传有效文件"));
}
return R.success(baseService.upload(file, attachmentVO));
}
判断具体使用哪个上传
/**
* 文件上传
*
* @param file 文件
* @param fileUploadVO 文件上传参数
* @return 文件对象
*/
public File upload(MultipartFile file, FileUploadVO fileUploadVO) {
FileStrategy fileStrategy = getFileStrategy(FileStorageType.CLOUD_FLARE);
return fileStrategy.upload(file, fileUploadVO.getBucket(), fileUploadVO.getBizType());
}
private FileStrategy getFileStrategy(FileStorageType storageType) {
storageType = storageType == null ? fileServerProperties.getStorageType() : storageType;
FileStrategy fileStrategy = contextStrategyMap.get(storageType.name());
ArgumentAssert.notNull(fileStrategy, "请配置正确的文件存储类型");
return fileStrategy;
}
getFileStrategy方法会确定最终使用哪个策略
end!!!