核心逻辑 controller
@RestController
public class MediaFilesController {
@Autowired
MediaFileService mediaFileService;
/**上传图片*/
@RequestMapping(value = "/upload/coursefile",consumes={MediaType.MULTIPART_FORM_DATA_VALUE})
public UploadFileResultDto upload(@RequestPart("filedata") MultipartFile file, //将multipart/form-data类型数据映射到控制器处理方法的参数中
@RequestParam(value = "folder",required=false) String folder,//将请求参数绑定到控制器的方法参数上
@RequestParam(value = "objectName",required = false) String objectName){
//主键id测试
Long companyId = 1232141425L;
//封装请求参数
UploadFileParamsDto uploadFileParamsDto = new UploadFileParamsDto();
String contentType = file.getContentType();
uploadFileParamsDto.setContentType(contentType);
uploadFileParamsDto.setFileSize(file.getSize());//文件大小
if (contentType.indexOf("image") >= 0) {
//是个图片
uploadFileParamsDto.setFileType("001001");
} else {
//代表其他文件
uploadFileParamsDto.setFileType("001003");
}
uploadFileParamsDto.setFilename(file.getOriginalFilename());//文件名称
UploadFileResultDto uploadFileResultDto = null;
try {
uploadFileResultDto = mediaFileService.uploadFile(companyId, uploadFileParamsDto, file.getBytes(), folder, objectName);
} catch (Exception e) {
XueChengPlusException.cast("上传文件过程中出错");
}
return uploadFileResultDto;
}
}
service
public interface MediaFileService {
/**
* @description 上传图片的通用接口
*/
public UploadFileResultDto uploadFile(Long companyId,UploadFileParamsDto uploadFileParamsDto,byte[] bytes,String folder,String objectName);
/**当前代理对象调用的入库接口*/
public MediaFiles addMediaFilesToDb(Long companyId,String fileMd5,UploadFileParamsDto uploadFileParamsDto,String objectName);
}
实现类
@Slf4j
@Service
public class MediaFileServiceImpl implements MediaFileService {
@Autowired
MediaFilesMapper mediaFilesMapper;
@Autowired
MinioClient minioClient;
//注入当前代理对象MediaFileService
@Autowired
MediaFileService currentProxy;
//拿到minio上存储文件桶的名字
@Value("${minio.bucket.files}")
private String bucket_Files;
/**图片上传实现类*/
@Override
public UploadFileResultDto uploadFile(Long companyId, UploadFileParamsDto uploadFileParamsDto, byte[] bytes, String folder, String objectName) {
//使用md5生成文件名
String fileMd5 = DigestUtils.md5Hex(bytes);
//判断是否输入文件存储路径
if (StringUtils.isEmpty(folder)){
//如果为空按年月日自动生成路径
folder=getFileFolder(new Date(),true,true,true);
}else if (folder.indexOf("/")<0){
folder=folder+"/";
}
String fileName=uploadFileParamsDto.getFilename();
if (StringUtils.isEmpty(objectName)){
objectName=fileMd5+fileName.substring(fileName.lastIndexOf("."));
}
objectName=folder+objectName;
try {
//调用上传minio方法
addMediaFilesToMinIO(bytes,bucket_Files,objectName);
//使用代理对象调用入库方法,否则直接调用会导致事务失效
MediaFiles mediaFiles = currentProxy.addMediaFilesToDb(companyId, fileMd5, uploadFileParamsDto, objectName);
//返回数据
UploadFileResultDto uploadFileResultDto = new UploadFileResultDto();
BeanUtils.copyProperties(mediaFiles,uploadFileResultDto);
return uploadFileResultDto;
}catch (Exception e){
log.error("上传失败:{}",e.getMessage());
}
return null;
}
/**上传minio方法*/
private void addMediaFilesToMinIO(byte[] bytes,String bucket,String objectName){
try {
//将字节数组生成输入流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
//扩展名
String extension = null;
if(objectName.indexOf(".")>=0){
//文件扩展名
extension = objectName.substring(objectName.lastIndexOf("."));
}
String contentType = getMimeTypeByExtension(extension);
//上传minio
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.bucket(bucket_Files)
.object(objectName)
//InputStream stream, long objectSize 对象大小, long partSize 分片大小
.stream(byteArrayInputStream, byteArrayInputStream.available(), -1)
.contentType(contentType)
.build();
minioClient.putObject(putObjectArgs);
}catch (Exception e){
XueChengPlusException.cast("上传文件到文件系统出错");
}
}
/**入库方法
事务加在入库方法,文件上传方法如文件过大上传时间就会变长事务持续时间也会变长*/
@Transactional
public MediaFiles addMediaFilesToDb(Long companyId,String fileMd5,UploadFileParamsDto uploadFileParamsDto,String objectName) {
MediaFiles mediaFiles = mediaFilesMapper.selectById(fileMd5);
if (mediaFiles==null){
mediaFiles=new MediaFiles();
//拷贝基本信息
BeanUtils.copyProperties(uploadFileParamsDto, mediaFiles);
mediaFiles.setId(fileMd5);
mediaFiles.setFileId(fileMd5);
mediaFiles.setCompanyId(companyId);
mediaFiles.setUrl("/" + bucket_Files + "/" + objectName);
mediaFiles.setBucket(bucket_Files);
mediaFiles.setCreateDate(LocalDateTime.now());
mediaFiles.setStatus("1");
mediaFilesMapper.insert(mediaFiles);
}
return mediaFiles;
}
/**获取contentType方法*/
private String getMimeTypeByExtension(String extension){
String contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
if(StringUtils.isNotEmpty(extension)){
ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
if(extensionMatch!=null){
contentType = extensionMatch.getMimeType();
}
}
return contentType;
}
/**根据日期拼接目录*/
private String getFileFolder(Date date, boolean year, boolean month, boolean day){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//获取当前日期字符串
String dateString = sdf.format(new Date());
//取出年、月、日
String[] dateStringArray = dateString.split("-");
StringBuffer folderString = new StringBuffer();
if(year){
folderString.append(dateStringArray[0]);
folderString.append("/");
}
if(month){
folderString.append(dateStringArray[1]);
folderString.append("/");
}
if(day){
folderString.append(dateStringArray[2]);
folderString.append("/");
}
return folderString.toString();
}
}