/**
* 附件上传
*/
@PostMapping("/upload")
@ApiOperation("附件上传")
public ResultEntity<FileAttachmentRespVO> upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "type", required = false) Integer type) {
return ResultEntity.success(contractService.upload(file, type));
}
/**
* 附件下载
*/
@GetMapping("/download")
@ApiOperation("附件下载")
public ResultEntity<Void> download(@RequestParam String downloadFileName, HttpServletResponse response) {
contractService.download(downloadFileName, response);
return ResultEntity.success();
}
public FileAttachmentRespVO upload(MultipartFile file, Integer type) {
// 校验文件后缀
String originalFilename = file.getOriginalFilename();
if (!originalFilename.contains(".")) {
throw new BusinessRuntimeException(ResultCodeEnum.FILE_NOT_SUFFIX);
}
//校验上传文件大小
double fileSize = (double) file.getSize() / 1048576;
if (type != null){
switch (type) {
case 1:
if (fileSize > 10) {
throw new BusinessRuntimeException(ResultCodeEnum.DEFAULT_CHECK_FAILURE, "上传单个文件不能大于10M");
}
break;
}
}else {
if (fileSize > 200) {
throw new BusinessRuntimeException(ResultCodeEnum.DEFAULT_CHECK_FAILURE, "上传单个文件不能大于200M");
}
}
ResultEntity<FileUploadInfoDTO> result = fileRemoteClient.fileUpload(file);
return ResultEntityUtil.toVoData(result, FileAttachmentRespVO.class);
}
public void download(String downloadFileName, HttpServletResponse response) {
Response remoteResponse = fileRemoteClient.download(downloadFileName, DownloadTypeEnum.ATACHMENT.getEnumValue());
//原文件名称
Collection<String> collection = remoteResponse.headers().get("fileName");
String fileName = "";
Optional<String> first = collection.stream().findFirst();
if (first.isPresent()) {
fileName = first.get();
}
try (InputStream inputStream = remoteResponse.body().asInputStream();
ServletOutputStream outputStream = response.getOutputStream()) {
response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
byte[] b = new byte[1024];
int len;
//从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
} catch (IOException e) {
log.info(EnvConstant.DOWNLOAD_FAILED + e);
}
}
@Getter
@AllArgsConstructor
/**
* 文件下载方式枚举
*/
public enum DownloadTypeEnum implements CommonEnum {
ON_LINE(1, "在线预览"),
ATACHMENT(2, "附件下载")
;
private final Integer enumValue;
private final String enumText;
}
/**
* 文件服务feign客户端
*
* @author LZX
* @version 1.0
* @since 2022/07/08 上午10:45
*/
@FeignClient(name = "${feign-service.file.name}",
url = "${feign-service.file.url}",
contextId = "file"
)
@Component
public interface FileRemoteClient extends FileRemote {
@GetMapping(value = "file/downloadv2")
@ApiOperation("文件下载")
Response download(@RequestParam(value = "fileName") String fileName, @RequestParam(value = "type") Integer type);
}
public interface FileRemote {
/**
* 文件上传
*/
@PostMapping(value = "file/upload", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation("文件上传")
ResultEntity<FileUploadInfoDTO> fileUpload(@RequestPart MultipartFile file);
/**
* 文件下载
*/
@GetMapping(value = "file/download")
@ApiOperation("文件下载")
@Deprecated
void download(@RequestParam(value = "fileName") String fileName,@RequestParam(value = "type") Integer type, HttpServletResponse response);
}
/**
* @author Lizx
* @date 2022/06/30
* @what 描述:文件上传相关
*/
@Api(tags = "【公共 文件接口】 FileController", value = "【公共 文件接口】 FileController")
@RestController
@Slf4j
public class FileController implements FileRemote {
@Autowired
private FileService fileService;
@Override
public ResultEntity<FileUploadInfoDTO> fileUpload(MultipartFile file) {
if (file.isEmpty() || file.getSize() == 0) {
return (ResultEntity<FileUploadInfoDTO>) ResultEntity.failed(ResultCodeEnum.FILE_NOT_NULL, ResultCodeEnum.FILE_NOT_NULL.getMsg(), null);
}
return fileService.upload(file);
}
/**
* (value = "file")
* 文件下载
*
* @param fileName
* @param type
*/
public void download(String fileName, Integer type) {
int i = 1;
}
@Override
@GetMapping(value = {"file/download", "file/downloadv2"})
public void download(String fileName, Integer type, HttpServletResponse response) {
String bucket = fileService.getDbBucket(fileName);
DownloadResult downloadResult = fileService.download(bucket, fileName);
if (!downloadResult.getResult()) {
throw new BusinessRuntimeException(ResultCodeEnum.FILE_NOT_EXIST);
}
if (DownloadTypeEnum.ON_LINE.getEnumValue().equals(type)) {
// 按照在线预览方式下载
FileUtils.toOnline(downloadResult, response);
}
if (DownloadTypeEnum.ATACHMENT.getEnumValue().equals(type)) {
// 按照附件方式下载
String name = fileService.getFileOldName(fileName);
toAttachment(downloadResult, response, name);
}
}
public void toAttachment(DownloadResult downloadResult, HttpServletResponse response, String name) {
InputStream inputStream = downloadResult.getInputStream();
response.reset();
response.setContentType("application/octet-stream");
if (StringUtils.isEmpty(name)) {
name = downloadResult.getFileName();
}
try {
response.setHeader("fileName", URLEncoder.encode(name, "UTF-8"));
response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(name, "UTF-8"));
ServletOutputStream outputStream = response.getOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
inputStream.close();
outputStream.flush();
} catch (IOException var7) {
log.error("download result to attachment error !", var7);
}
}
}
/**
* @author Lizx
* @date 2022/06/30
* @what 描述:
*/
@Slf4j
@Service
public class FileService {
@Resource
AmazonS3Service amazonS3Service;
@Autowired
private FileSpInfoDao fileSpInfoDao;
@Autowired
private FileUploadDao fileUploadDao;
@Resource
private FileEnvConfig fileEnvConfig;
/**
* @param file
* @param
* @return
* @author lizx
* @date 2022/06/30
* @what 描述: 文件上传
*/
public ResultEntity upload(MultipartFile file) {
String bucket = getBucket();
String url = "";
if (ServiceClientEnum.CONTRACT_CENTER == RequestHelper.getRequestServiceClient()) {
url = fileEnvConfig.getContractEndpoint();
}else if (ServiceClientEnum.DIRECT_ORDER == RequestHelper.getRequestServiceClient()) {
url = fileEnvConfig.getOrderEndpoint();
}else{
throw new BusinessRuntimeException(ResultCodeEnum.DEFAULT_THIRD_SERVICE_ERROR,"未知服务异常");
}
long startTime = System.currentTimeMillis();
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
String key = "";
String urlStr = null;
long fileSize = file.getSize();
try {
UploadResult upload = amazonS3Service.upload(bucket, file);
if (!upload.getResult()) {
return ResultEntity.failed(ResultCodeEnum.FILE_UPLOAD_FAILED,ResultCodeEnum.FILE_UPLOAD_FAILED.getMsg(),null);
}
key = upload.getFileName();
urlStr = url + "/" + bucket + "/" + upload.getFileName();
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
log.info("上传到S3耗时:{}", endTime - startTime);
FileUploadInfoPO fileUploadInfoPO = new FileUploadInfoPO();
fileUploadInfoPO.setTenantId(1);
fileUploadInfoPO.setSpId(NumberConstants.INTEGER_1);
// 附件类型
fileUploadInfoPO.setFileName(key);
fileUploadInfoPO.setFileOldName(originalFilename);
fileUploadInfoPO.setFileSize(fileSize);
fileUploadInfoPO.setFileExt(suffix);
fileUploadInfoPO.setFileUrl(urlStr);
fileUploadInfoPO.setIsDeleted(false);
fileUploadInfoPO.setBucket(bucket);
fileUploadInfoPO.setCreateTime(new Date());
fileUploadInfoPO.setUpdateTime(new Date());
fileUploadDao.addFileUpload(fileUploadInfoPO);
FileUploadInfoDTO fileUploadInfoDTO = BeanUtils.copyProperties(fileUploadInfoPO, FileUploadInfoDTO.class);
fileUploadInfoDTO.setFileName(originalFilename);
fileUploadInfoDTO.setDownloadFileName(key);
return ResultEntity.success(fileUploadInfoDTO);
}
public DownloadResult download(String defaultBucket, String fileName) {
return amazonS3Service.download(defaultBucket, fileName);
}
}
/**
* @author Lizx
* @date 2022/06/30
* @what 描述:
*/
@Slf4j
@Service
public class AmazonS3Service {
@Resource
@Qualifier("contract")
private AmazonS3 amazonS3Contract;
@Resource(name = "order")
private AmazonS3 amazonS3Order;
public UploadResult upload(String bucket, MultipartFile multipartFile) {
Assert.notNull(multipartFile,"file cannot be null");
String fileExtName = "";
if(multipartFile.getOriginalFilename() != null){
String [] nameArr = multipartFile.getOriginalFilename().split("\\.");
if(nameArr.length > 1){
fileExtName = nameArr[nameArr.length-1];
}
}
String fileName = genFileName(fileExtName);
return uploadOne(bucket,fileName,multipartFile);
}
public UploadResult uploadOne(String bucket, String fileName, MultipartFile multipartFile) {
Assert.notNull(bucket,"bucket can not be null");
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
objectMetadata.setContentLength(multipartFile.getSize());
try {
if (ServiceClientEnum.CONTRACT_CENTER == RequestHelper.getRequestServiceClient()) {
amazonS3Contract.putObject(new PutObjectRequest(bucket, fileName, multipartFile.getInputStream(), objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
}else if (ServiceClientEnum.DIRECT_ORDER == RequestHelper.getRequestServiceClient()) {
amazonS3Order.putObject(new PutObjectRequest(bucket, fileName, multipartFile.getInputStream(), objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
}else{
throw new BusinessRuntimeException(ResultCodeEnum.DEFAULT_THIRD_SERVICE_ERROR,"未知服务异常");
}
}catch (Exception e){
log.error("ironhide upload failed, type:aws,reason:{}",e);
return new UploadResult(false,e.getMessage());
}
UploadResult uploadResult = new UploadResult(true,bucket,fileName);
uploadResult.setOriginalFilename(multipartFile.getOriginalFilename());
uploadResult.setFileSize(multipartFile.getSize());
return uploadResult;
}
protected String genFileName(String fileExtName) {
if(fileExtName == null){
fileExtName = "";
}
//生成一个文件名
return UUID.randomUUID().toString().replaceAll("-", "")
+ RandomStringUtils.randomAlphanumeric(4)
+ "." + fileExtName;
}
public DownloadResult download(String bucket, String fileName) {
Assert.notNull(bucket,"bucket can not be null");
DownloadResult downloadResult = new DownloadResult();
try {
downloadResult.setResult(true);
downloadResult.setBucket(bucket);
downloadResult.setFileName(fileName);
if (ServiceClientEnum.CONTRACT_CENTER == RequestHelper.getRequestServiceClient()) {
S3Object s3Object = amazonS3Contract.getObject(bucket,fileName);
downloadResult.setInputStream(s3Object.getObjectContent());
}else if (ServiceClientEnum.DIRECT_ORDER == RequestHelper.getRequestServiceClient()) {
S3Object s3Object = amazonS3Order.getObject(bucket,fileName);
downloadResult.setInputStream(s3Object.getObjectContent());
}else{
throw new BusinessRuntimeException(ResultCodeEnum.DEFAULT_THIRD_SERVICE_ERROR,"未知服务异常");
}
}catch (Exception e){
log.error("ironhide download failed, type:aws,reason:{}",e);
downloadResult.setResult(false);
return downloadResult;
}
return downloadResult;
}
}
/**
* @Author: lzx
* @Date: 2022/11/11 16:21
* @What: 描述:
*/
@Getter
@Setter
@Configuration
public class AmazonS3Configure {
@Resource
private FileEnvConfig fileEnvConfig;
/**
* 初始化生成AmazonS3 客户端配置
* @return
*/
@Bean(name = "contract")
public AmazonS3 s3clientContract() {
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(fileEnvConfig.getContractEndpoint(), Region.getRegion(Regions.CN_NORTH_1).getName());
AWSCredentials awsCredentials = new BasicAWSCredentials(fileEnvConfig.getContractAccessKey(),fileEnvConfig.getContractSecretKey());
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTP);
AmazonS3 S3client = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(awsCredentialsProvider)
.disableChunkedEncoding()
.withPathStyleAccessEnabled(true)
.withForceGlobalBucketAccessEnabled(true)
.build();
return S3client;
}
/**
* 初始化生成AmazonS3 客户端配置
* @return
*/
@Bean(name = "order")
public AmazonS3 s3clientOrder() {
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(fileEnvConfig.getOrderEndpoint(), Region.getRegion(Regions.CN_NORTH_1).getName());
AWSCredentials awsCredentials = new BasicAWSCredentials(fileEnvConfig.getOrderAccessKey(),fileEnvConfig.getOrderSecretKey());
AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setProtocol(Protocol.HTTP);
AmazonS3 S3client = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(awsCredentialsProvider)
.disableChunkedEncoding()
.withPathStyleAccessEnabled(true)
.withForceGlobalBucketAccessEnabled(true)
.build();
return S3client;
}
}
s3:
contract:
# 对象存储服务器端点地址
serviceEndpoint: http://lzx.com:8080
# 访问授权 s3必填
accessKey: 3X66RXHSY8CHSGAJ
secretKey: SCSXjskcfsXsjwf//7HXSu8hx7Xshr7J
defaultBucket: contract-tst
region: us-east-1
order:
serviceEndpoint: http://lzx.com:8080
accessKey: Snhv7shdkHskr8sJ
secretKey: u8hx7Xshr7JSCsXsjwf//7HXSSXjskcn
defaultBucket: order-tst
region: us-east-1
feign-service:
file:
name: lzx-file-service
url:
feign实现文件上传下载
于 2023-07-11 10:34:33 首次发布