add-实现上传并记录

This commit is contained in:
zhangran 2021-08-02 17:54:23 +08:00
parent 9d69d0d727
commit d454a6380c
16 changed files with 279 additions and 15 deletions

View File

@ -31,8 +31,7 @@ public class ServerFileController implements ServerFileServiceApi {
@Override @Override
public CommonResponse<ServerFileUploadResponse> upload(@Valid @RequestBody ServerFileUploadRequest request) { public CommonResponse<ServerFileUploadResponse> upload(@Valid @RequestBody ServerFileUploadRequest request) {
ServerFileUploadDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadDto.class); ServerFileUploadDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadDto.class);
fileService.upload(dto); return CommonResponse.success(fileService.upload(dto));
return null;
} }
/** /**

View File

@ -4,12 +4,12 @@ spring:
cloud: cloud:
nacos: nacos:
config: config:
server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80} server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
file-extension: yaml file-extension: yaml
namespace: ${NACOS_NAMESPACE_ID:f82179f1-81a9-41a1-a489-4f9ab5660a6e} namespace: ${NACOS_NAMESPACE_ID:8921646d-ff54-4fd4-a258-2f80ce21142d}
prefix: ${spring.application.name} prefix: ${spring.application.name}
profiles: profiles:
active: ${NACOS_PROFILES_ACTIVE:local} active: ${NACOS_PROFILES_ACTIVE:dev}
main: main:
allow-bean-definition-overriding: true allow-bean-definition-overriding: true

View File

@ -37,6 +37,9 @@ public enum CodeEnum implements EnumBase<Integer> {
NO_CHANNELS_AVAILABLE(105,"no channels available"), NO_CHANNELS_AVAILABLE(105,"no channels available"),
NO_UPLOAD_CONFIG(106,"no upload config"), NO_UPLOAD_CONFIG(106,"no upload config"),
FILE_SIZE_EXCEEDS_LIMIT(107,"file size exceeds limit"), FILE_SIZE_EXCEEDS_LIMIT(107,"file size exceeds limit"),
NOT_FILE_FORMAT(108,"failed to get file format"),
FILE_FORMAT_NOT_SUPPORTED(109,"file format is not supported"),
FILE_UPLOAD_FAILED(109,"file upload failed"),
; ;

View File

@ -0,0 +1,35 @@
package cn.axzo.oss.common.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* @author: zhangran
* @date: 20210802 14:48
* @description:
**/
@Getter
@RequiredArgsConstructor
public enum FileStatusEnum implements EnumBase<Integer> {
/**
* 处理中
*/
STATUS_PROCESSING(0, "处理中"),
/**
* 上传成功
*/
STATUS_UPLOAD_SUCCESS(1, "上传成功"),
/**
* 上传失败
*/
STATUS_UPLOAD_FAIL(2, "上传失败"),
/**
* 已删除
*/
STATUS_DELETE(3, "已删除"),
;
private final Integer code;
private final String message;
}

View File

@ -5,6 +5,7 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Objects; import java.util.Objects;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
@ -102,4 +103,12 @@ public class Utility {
} }
return storageUnitEnum.getSize() * size; return storageUnitEnum.getSize() * size;
} }
/**
* 生成UUID
* @return
*/
public static String getUUID(){
return UUID.randomUUID().toString().replaceAll("-","");
}
} }

View File

@ -10,4 +10,9 @@ import cn.axzo.oss.integration.s3.base.BaseS3Service;
**/ **/
public interface AliOssService extends BaseS3Service { public interface AliOssService extends BaseS3Service {
/**
* get endpoint
* @return
*/
String getEndpoint();
} }

View File

@ -20,8 +20,7 @@ public interface BaseS3Service {
/** /**
* upload file * upload file
*/ */
boolean uploadByStream(InputStream srcStream, String tgtFileKey); String uploadByStream(String bucketName, String tgtFileKey, InputStream srcStream);
/** /**
* upload multi file * upload multi file
@ -51,4 +50,6 @@ public interface BaseS3Service {
*/ */
FilterInputStream getS3ObjectStream(String tgtFileKey); FilterInputStream getS3ObjectStream(String tgtFileKey);
} }

View File

@ -12,4 +12,6 @@ public interface OssClientBase {
void initClient(); void initClient();
String getEndpoint();
} }

View File

@ -47,4 +47,9 @@ public class AliOssClient implements OssClientBase {
} }
} }
@Override
public String getEndpoint(){
return aliOssConfig.getEndpoint();
}
} }

View File

@ -1,8 +1,11 @@
package cn.axzo.oss.integration.s3.impl; package cn.axzo.oss.integration.s3.impl;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.integration.s3.AliOssService; import cn.axzo.oss.integration.s3.AliOssService;
import cn.axzo.oss.integration.s3.client.AliOssClient; import cn.axzo.oss.integration.s3.client.AliOssClient;
import com.aliyun.oss.ClientException; import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException; import com.aliyun.oss.OSSException;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.InputStream; import java.io.InputStream;
@ -29,8 +32,28 @@ public class AliOssServiceImpl implements AliOssService {
* upload file * upload file
*/ */
@Override @Override
public boolean uploadByStream(InputStream srcStream, String tgtFileKey) { public String uploadByStream(String bucketName, String tgtFileKey, InputStream srcStream) {
return false; OSS client = aliOssClient.getClient();
try {
client.putObject(bucketName, tgtFileKey, srcStream);
} catch (OSSException e) {
log.error("uploadByStream OSSException", e);
return "";
} catch (ClientException e) {
log.error("uploadByStream ClientException", e);
return "";
} finally {
client.shutdown();
}
StringBuilder allBuilder = new StringBuilder();
allBuilder.append("https://");
allBuilder.append(bucketName);
allBuilder.append(".");
allBuilder.append(aliOssClient.getEndpoint());
allBuilder.append(tgtFileKey);
return allBuilder.toString();
} }
/** /**
@ -51,7 +74,7 @@ public class AliOssServiceImpl implements AliOssService {
aliOssClient.getClient().deleteObject(bucket, tgtFileKey); aliOssClient.getClient().deleteObject(bucket, tgtFileKey);
return Boolean.TRUE; return Boolean.TRUE;
} catch (Exception e) { } catch (Exception e) {
log.error("ali oss delFile error = {}",e); log.error("ali oss delFile error = {}", e);
} }
return Boolean.FALSE; return Boolean.FALSE;
} }
@ -81,4 +104,9 @@ public class AliOssServiceImpl implements AliOssService {
public FilterInputStream getS3ObjectStream(String tgtFileKey) { public FilterInputStream getS3ObjectStream(String tgtFileKey) {
return null; return null;
} }
@Override
public String getEndpoint() {
return aliOssClient.getEndpoint();
}
} }

View File

@ -11,4 +11,21 @@ import cn.axzo.oss.dal.entity.File;
public interface FileManager { public interface FileManager {
boolean delete(File file); boolean delete(File file);
/**
* 上传
*
* @param bulkName
* @param keyPath
* @param fileContent
* @return
*/
String uploadByStream(String bulkName, String keyPath, byte[] fileContent);
/**
* get endpoint
*
* @return
*/
String getAliOssEndpoint();
} }

View File

@ -0,0 +1,28 @@
package cn.axzo.oss.manager.api.dto.response;
import lombok.Data;
/**
* 服务端文件上传响应类
*
* @author zhaoyong
* @see ServerFileUploadResponse
* @since 2021-07-23 10:37
*/
@Data
public class ServerFileUploadResponse {
/**
* 文件 URL
*/
private String url;
/**
* 文件 Key
*/
private String fileKey;
/**
* URL MD5
*/
private String urlMd5;
}

View File

@ -2,8 +2,16 @@ package cn.axzo.oss.manager.impl;
import cn.axzo.oss.dal.entity.File; import cn.axzo.oss.dal.entity.File;
import cn.axzo.oss.integration.s3.AliOssService; import cn.axzo.oss.integration.s3.AliOssService;
import cn.axzo.oss.integration.s3.config.AliOssConfig;
import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.FileManager;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -24,4 +32,24 @@ public class FileManagerImpl implements FileManager {
public boolean delete(File file) { public boolean delete(File file) {
return aliOssService.delFile(file.getBucketName(), file.getFileUuid()); return aliOssService.delFile(file.getBucketName(), file.getFileUuid());
} }
/**
* @param bulkName 默认的取值为
* @param keyPath key的前置路径
*/
public String uploadByStream(String bulkName, String keyPath, byte[] fileContent) {
InputStream inputStream = new ByteArrayInputStream(fileContent);
return aliOssService.uploadByStream(bulkName, keyPath, inputStream);
}
/**
* get endpoint
*
* @return
*/
public String getAliOssEndpoint() {
return aliOssService.getEndpoint();
}
} }

View File

@ -2,6 +2,7 @@ package cn.axzo.oss.service.api;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
/** /**
* @Author admin * @Author admin
@ -23,5 +24,5 @@ public interface FileService {
* *
* @param request * @param request
*/ */
void upload(ServerFileUploadDto request); ServerFileUploadResponse upload(ServerFileUploadDto request);
} }

View File

@ -3,6 +3,7 @@ package cn.axzo.oss.service.impl;
import cn.axzo.oss.common.constans.CommonConstants.FileStatus; import cn.axzo.oss.common.constans.CommonConstants.FileStatus;
import cn.axzo.oss.common.constans.CommonConstants.TableDelete; import cn.axzo.oss.common.constans.CommonConstants.TableDelete;
import cn.axzo.oss.common.enums.CodeEnum; import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.enums.FileStatusEnum;
import cn.axzo.oss.common.exception.BizException; import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.common.utils.JsonUtil; import cn.axzo.oss.common.utils.JsonUtil;
import cn.axzo.oss.common.utils.Utility; import cn.axzo.oss.common.utils.Utility;
@ -22,9 +23,11 @@ import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.api.FileService;
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -58,6 +61,7 @@ public class FileServiceImpl implements FileService {
@Autowired @Autowired
private FileUploadConfigDao fileUploadConfigDao; private FileUploadConfigDao fileUploadConfigDao;
/** /**
* 删除文件 * 删除文件
* *
@ -94,8 +98,9 @@ public class FileServiceImpl implements FileService {
* @param dto * @param dto
*/ */
@Override @Override
public void upload(ServerFileUploadDto dto) { public ServerFileUploadResponse upload(ServerFileUploadDto dto) {
log.info("update dto:{}", JSON.toJSONString(dto)); log.info("update fileName:{},appCode:{},bizScene:{}",
dto.getFileName(), dto.getAppCode(), dto.getBizScene());
/** /**
* 1.检查app * 1.检查app
* 2.渠道 * 2.渠道
@ -133,6 +138,10 @@ public class FileServiceImpl implements FileService {
AppChannelBucket appChannelBucket = appChannelBuckets.stream().filter(bucket -> AppChannelBucket appChannelBucket = appChannelBuckets.stream().filter(bucket ->
bucket.getChannelCode().equals(fileChannel.getChannelCode())) bucket.getChannelCode().equals(fileChannel.getChannelCode()))
.findFirst().orElse(null); .findFirst().orElse(null);
if (appChannelBucket == null) {
log.error("upload 最优渠道为空 channels:{}", channels);
throw new BizException(CodeEnum.APP_CHANNEL_NOT_FOUND);
}
// 通过渠道桶编码获取到具体文件业务场景 // 通过渠道桶编码获取到具体文件业务场景
FileBusinessScene scene = fileBusinessSceneDao FileBusinessScene scene = fileBusinessSceneDao
@ -158,7 +167,67 @@ public class FileServiceImpl implements FileService {
, size); , size);
throw new BizException(CodeEnum.FILE_SIZE_EXCEEDS_LIMIT); throw new BizException(CodeEnum.FILE_SIZE_EXCEEDS_LIMIT);
} }
// todo 文件格式判断 // 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(",");
int lastIndexOf = dto.getFileName().lastIndexOf(".");
if (lastIndexOf == -1) {
log.error("获取文件格式失败:{}", dto.getFileName());
throw new BizException(CodeEnum.NOT_FILE_FORMAT);
}
String fileFormats = dto.getFileName().substring(lastIndexOf + 1).toLowerCase();
boolean contains = Arrays.asList(formats).contains(fileFormats);
if (!contains) {
log.error("不支持此格式文件fileName:{},formats:{}", dto.getFileName(), formats);
throw new BizException(CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
}
String md5 = Utility.getMd5(dto.getFileContent());
File ossFile = new File();
ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo());
ossFile.setAppCode(fileUploadConfig.getAppCode());
ossFile.setChannelCode(fileUploadConfig.getChannelCode());
ossFile.setBucketName(fileUploadConfig.getBucketName());
ossFile.setDirectory(fileUploadConfig.getDirectory());
ossFile.setFileMd5(md5);
ossFile.setStatus(FileStatusEnum.STATUS_PROCESSING.getCode());
ossFile.setFileFormat(fileFormats);
ossFile.setFileName(dto.getFileName());
ossFile.setStorageUnit(fileUploadConfig.getStorageUnit());
ossFile.setStorageSize(fileUploadConfig.getStorageSize());
String uuid = Utility.getUUID();
// 上传文件
StringBuilder builder = new StringBuilder();
builder.append(fileUploadConfig.getDirectory());
builder.append("/");
builder.append(uuid);
builder.append(".");
builder.append(fileFormats);
String fileUrl = fileManager.uploadByStream(
fileUploadConfig.getBucketName(), builder.toString(), dto.getFileContent());
if (Utility.isBlank(fileUrl)) {
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode());
fileDao.save(ossFile);
throw new BizException(CodeEnum.FILE_UPLOAD_FAILED);
}
ossFile.setFileUuid(uuid);
ossFile.setFileUrl(fileUrl);
ossFile.setUrlMd5(Utility.getMd5(fileUrl));
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode());
fileDao.save(ossFile);
ServerFileUploadResponse response = new ServerFileUploadResponse();
response.setUrl(ossFile.getFileUrl());
response.setUrlMd5(ossFile.getUrlMd5());
response.setFileKey(ossFile.getFileUuid());
return response;
} }
} }

View File

@ -1,8 +1,15 @@
package cn.axzo.oss.test; package cn.axzo.oss.test;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.api.FileService;
import cn.axzo.oss.test.base.SpringTestBase; import cn.axzo.oss.test.base.SpringTestBase;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -18,11 +25,38 @@ public class FileServiceTest extends SpringTestBase {
private FileService fileService; private FileService fileService;
@Test @Test
public void deleteTest(){ public void deleteTest() {
ServerFileDeleteDto dto = new ServerFileDeleteDto(); ServerFileDeleteDto dto = new ServerFileDeleteDto();
dto.setUrl("https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/stable/face/19700101080046_6296.jpg"); dto.setUrl("https://axzo-pro.oss-cn-hangzhou.aliyuncs.com/stable/face/19700101080046_6296.jpg");
dto.setOperator("zhangsan"); dto.setOperator("zhangsan");
fileService.delete(dto); fileService.delete(dto);
} }
@Test
public void upload() {
ServerFileUploadDto dto = new ServerFileUploadDto();
dto.setAppCode("test");
dto.setBizScene("1");
dto.setFileName("一个新的文件.jpg");
File file = new File("/Users/zhangran/Desktop/xx/IMG_20210728_162815.jpg");
FileInputStream fileInputStream = null;
byte[] bytes = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
fileInputStream.read(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
dto.setFileContent(bytes);
fileService.upload(dto);
}
} }