springboot上传图片到minio

299 阅读2分钟

核心逻辑 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();
    }

}