前言
之前用到文件上传功能,在这里做个学习记录。使用minio实现,后面会记录使用fastdfs和阿里云的oss实现文件上传以及他们的比较(oss根据流量收费)。minio的中文文档:https://docs.min.io/cn/
minio安装
- 首先查询docker镜像:
docker search minio
- 选着stars最高的那个拉取:
docker pull minio/minio
- 启动minio服务器,并设置端口号,容器名,账号和密码:
docker run -p 9000:9000 --name minio -e MINIO_ACCESS_KEY=tanchuntcc -e MINIO_SECRET_KEY=tanchuntcc -v /data:/data minio/minio server /data
minio操作
- 启动成功后,访问你minio的ip地址,这里我docker安装在本机,所以是http://localhost:9000,输入刚刚设置的账号密码。
- 登陆后右下角可以创建bucket.
- 创建多个bucket后
- 可以选择编辑和删除
- 可以点击右下角上传文件
- 支持各种类型的文件:
Java客户端
首先创建一个Springboot项目,在resources中的application.yml文件添加如下配置:
server:port: 8080spring:servlet:multipart:enabled: true #开启文件上传max-file-size: 500MBmax-request-size: 500MBminio:endpoint: http://localhost:9000 #Minio服务所在地址bucketName: tcc #存储桶名称accessKey: tanchuntcc #访问的keysecretKey: tanchuntcc #访问的秘钥
添加minio的maven依赖:
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>3.0.10</version></dependency>
controller的代码如下:
@RestController("/minioDemo")
public class MinioDemoController {private static final Logger LOGGER = LoggerFactory.getLogger(MinioDemoController.class);@Value("${minio.endpoint}")private String ENDPOINT;@Value("${minio.bucketName}")private String BUCKETNAME;@Value("${minio.accessKey}")private String ACCESSKEY;@Value("${minio.secretKey}")private String SECRETKEY;//文件创建@PostMappingpublic String upload(MultipartFile file) {String s=null;try {MinioClient minioClient = new MinioClient(ENDPOINT, ACCESSKEY, SECRETKEY);//存入bucket不存在则创建,并设置为只读if (!minioClient.bucketExists(BUCKETNAME)) {minioClient.makeBucket(BUCKETNAME);minioClient.setBucketPolicy(BUCKETNAME, "*.*", PolicyType.READ_ONLY);}String filename = file.getOriginalFilename();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 文件存储的目录结构String objectName = sdf.format(new Date()) + "/" + filename;// 存储文件minioClient.putObject(BUCKETNAME, objectName, file.getInputStream(), file.getContentType());LOGGER.info("文件上传成功!");s=ENDPOINT + "/" + BUCKETNAME + "/" + objectName;} catch (Exception e) {LOGGER.info("上传发生错误: {}!", e.getMessage());}return s;}//文件删除@DeleteMappingpublic String delete(String name) {try {MinioClient minioClient = new MinioClient(ENDPOINT, ACCESSKEY, SECRETKEY);minioClient.removeObject(BUCKETNAME, name);} catch (Exception e) {return "删除失败"+e.getMessage();}return "删除成功";}
}@GetMappingpublic void downloadFiles(@RequestParam("filename") String filename, HttpServletResponse httpResponse) {try {MinioClient minioClient = new MinioClient(ENDPOINT, ACCESSKEY, SECRETKEY);InputStream object = minioClient.getObject(BUCKETNAME, filename);byte buf[] = new byte[1024];int length = 0;httpResponse.reset();httpResponse.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));httpResponse.setContentType("application/octet-stream");httpResponse.setCharacterEncoding("utf-8");OutputStream outputStream = httpResponse.getOutputStream();while ((length = object.read(buf)) > 0) {outputStream.write(buf, 0, length);}outputStream.close();} catch (Exception ex) {LOGGER.info("导出失败:", ex.getMessage());}}
编写好demo程序后使用postman进行测试:使用postman文件上传时选择body中的form-data选项,然后属性栏里面选择file属性就可以实现文件上传了。
删除文件时输入文件的相对路径即可删除:
导出文件时填好文件名称,选择save and download即可在postman中导出文件: