安装minio参考Docker 搭建 MinIO_letterss的博客-优快云博客
pom
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.2</version>
</dependency>
application.properties
#minio配置
minio.endpoint= http://192.168.32.1:9000
minio.accesskey= minio
minio.secretKey= minio
minio配置类
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* auth: ws
*
* minio配置类
*/
@Data
@Component
public class MinioProp {
@Value("${minio.endpoint}")
private String endpoint;
@Value("${minio.accesskey}")
private String accesskey;
@Value("${minio.secretKey}")
private String secretKey;
}
minio客户端配置
import io.minio.MinioClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* auth: ws
* <p>
* minio客户端配置
*/
@Configuration
public class MinioConfiguration {
@Resource
private MinioProp minioProp;
@Bean
public MinioClient minioClient() {
MinioClient minioClient = MinioClient.builder()
.endpoint(minioProp.getEndpoint())
.credentials(minioProp.getAccesskey(), minioProp.getSecretKey())
.build();
return minioClient;
}
}
数据库
CREATE TABLE `file_manage` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`file_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '文件名称',
`file_id` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '文件id',
`bucket` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '存储桶',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
实体类
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* <p>
* 文件管理
* </p>
*
* @author ws
* @since 2021-11-18
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="FileManage对象", description="文件管理")
public class FileManage implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "文件名称")
private String fileName;
@ApiModelProperty(value = "文件id")
private String fileId;
@ApiModelProperty(value = "存储桶")
private String bucket;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date createTime;
public FileManage(String fileName, String fileId, String bucket, Date createTime) {
this.fileName = fileName;
this.fileId = fileId;
this.bucket = bucket;
this.createTime = createTime;
}
}
mapper
public interface FileManageMapper extends BaseMapper<FileManage> {
}
service
/**
* <p>
* 文件管理 服务类
* </p>
*
* @author ws
* @since 2021-11-18
*/
public interface IFileManageService extends IService<FileManage> {
List<FileManage> getRelFileName(List<String> list);
}
serviceImpl
/**
* <p>
* 文件管理 服务实现类
* </p>
*
* @author ws
* @since 2021-11-18
*/
@Service
public class FileManageServiceImpl extends ServiceImpl<FileManageMapper, FileManage> implements IFileManageService {
/**
* 根据文件唯一标识,查询文件名
* @param list
* @return
*/
@Override
public List<FileManage> getRelFileName(List<String> list){
QueryWrapper<FileManage> fileInfoQueryWrapper = new QueryWrapper<>();
fileInfoQueryWrapper.in("file_id",list).select("file_id","file_name","bucket");
List<FileManage> platformFileInfos = this.list(fileInfoQueryWrapper);
return platformFileInfos;
}
}
BaseException
public class BaseException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 所属模块
*/
private String module;
/**
* 错误码
*/
private String code;
/**
* 错误码对应的参数
*/
private Object[] args;
/**
* 错误消息
*/
private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage)
{
this.module = module;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public BaseException(String module, String code, Object[] args)
{
this(module, code, args, null);
}
public BaseException(String module, String defaultMessage)
{
this(module, null, null, defaultMessage);
}
public BaseException(String code, Object[] args)
{
this(null, code, args, null);
}
public BaseException(String defaultMessage)
{
this(null, null, null, defaultMessage);
}
public String getModule()
{
return module;
}
public String getCode()
{
return code;
}
public Object[] getArgs()
{
return args;
}
public String getDefaultMessage()
{
return defaultMessage;
}
}
方法工具类
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.flink.streaming.web.common.RestResult;
import com.flink.streaming.web.common.util.BaseException;
import com.flink.streaming.web.model.entity.FileManage;
import com.flink.streaming.web.service.IFileManageService;
import io.minio.*;
import io.minio.messages.Bucket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
/**
* auth: ws
* <p>
* 文件服务
*/
@Slf4j
@RestController
@RequestMapping("/file")
@Api(value = "/file", description = "文件服务")
public class FileController {
@Autowired
private MinioClient minioClient;
@Autowired
IFileManageService fileInfoService;
@ApiOperation("上传文件")
@PostMapping("/upload")
public RestResult upload(@RequestParam(name = "file", required = false) MultipartFile[] file, @RequestParam(name = "bucket") String bucket) {
if (file == null || file.length == 0) {
return RestResult.error("上传文件不能为空");
}
if (StringUtils.isBlank(bucket)) {
return RestResult.error("文件桶不能为空");
}
List<String> orgfileNameList = new ArrayList<>(file.length);
for (MultipartFile multipartFile : file) {
String orgfileName = multipartFile.getOriginalFilename();
String fileId =UUID.randomUUID().toString().replaceAll("-","");
try {
InputStream in = multipartFile.getInputStream();
//minioClient.putObject(minioBucket, orgfileName, in, new PutObjectOptions(in.available(), -1));
ObjectWriteResponse objectWriteResponse = minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucket)
.object(fileId)
.stream(in, in.available(), -1)
.build());
in.close();
boolean save = fileInfoService.save(new FileManage(orgfileName, fileId, bucket, new Date()));
if (!save) {
log.error("文件保存数据库失败, bucket: {} fileId: {} fileName: {}", bucket, fileId, orgfileName);
return RestResult.error("文件保存数据库失败");
}
orgfileNameList.add(fileId);
} catch (Exception e) {
log.error(e.getMessage());
return RestResult.error("上传失败");
}
}
Map<String, Object> data = new HashMap<String, Object>();
data.put("bucketName", bucket);
data.put("fileName", orgfileNameList);
return RestResult.success(data);
}
@ApiOperation("列出buckets列表")
@GetMapping("/listBuckets")
public RestResult<List<String>> listBuckets() {
List<Bucket> bucketList = null;
try {
bucketList = minioClient.listBuckets();
} catch (Exception e) {
log.error(e.getMessage());
return RestResult.error("获取文件桶列表失败");
}
ArrayList<String> ret = new ArrayList<>();
for (Bucket bucket : bucketList) {
ret.add(bucket.name());
}
return RestResult.success(ret);
}
@ApiOperation("获取资源文件")
@GetMapping(value = {"/download/{fileId}"})
public void download(HttpServletResponse response, @PathVariable("fileId") String fileId) {
try {
QueryWrapper<FileManage> fileInfoQueryWrapper = new QueryWrapper<>();
HashMap<String, String> queryMap = new HashMap<>();
queryMap.put("file_id", fileId);
FileManage fileInfo = fileInfoService.getOne(fileInfoQueryWrapper.allEq(queryMap, false));
if (fileInfo == null) {
throw new BaseException("资源不存在");
}
//response.setContentType(stat.contentType());
GetObjectResponse getObjectResponse =
minioClient.getObject(
GetObjectArgs.builder().bucket(fileInfo.getBucket()).object(fileId).build());
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileInfo.getFileName(), "UTF-8"));
IOUtils.copy(getObjectResponse, response.getOutputStream());
} catch (Exception e) {
log.error(e.getMessage());
}
}
@ApiOperation("删除资源文件")
@DeleteMapping(value = {"/del/{bucket}/{fileId}"})
public RestResult delete(@PathVariable(value = "bucket") String bucket, @PathVariable("fileId") String fileId) {
try {
QueryWrapper<FileManage> fileInfoQueryWrapper = new QueryWrapper<>();
HashMap<String, String> queryMap = new HashMap<>();
queryMap.put("file_id", fileId);
queryMap.put("bucket", bucket);
fileInfoService.remove(fileInfoQueryWrapper.allEq(queryMap, false));
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket(bucket)
.object(fileId)
.build()
);
} catch (Exception e) {
log.error(e.getMessage());
return RestResult.error("删除失败");
}
return RestResult.success();
}
@ApiOperation("根据文件标识获取文件名")
@PostMapping(value = {"/query"})
public RestResult<List<FileManage>> query(@RequestBody List<String> fileIds) {
List<FileManage> relFileNames = fileInfoService.getRelFileName(fileIds);
return RestResult.success(relFileNames);
}
}