首页 OES之九:文件上传下载
文章
取消

OES之九:文件上传下载

上传至服务器本地

上传到服务器本地的指定文件夹下,需要判断目录是否存在,如果不存在就创建,创建好之后就可以把 MultipartFile 对象存在指定位置了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.oes.biz.service.FileService;
import org.oes.common.config.BizConfigurations;
import org.oes.common.constans.OesConstant;
import org.oes.common.exception.OesServiceException;
import org.oes.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

public class FileServiceImpl implements FileService {
    @Override
    public void uploadFile(MultipartFile file, String fileName) {
        if (StringUtils.isBlank(fileName)) {
            fileName = file.getOriginalFilename();
        }
        File dest = new File( BizConfigurations.avatarDictionary + "/" + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest);
        } catch (Exception e) {
            throw new OesServiceException("文件" + file.getOriginalFilename() + "上传失败");
        }
    }
}

测试

1
2
3
4
5
6
7
8
9
10
    @RequestMapping(value = "file/upload", method = RequestMethod.POST)
    public String fileUp(@RequestParam("files") MultipartFile[] files) {
        JSONObject object=new JSONObject();
        for (MultipartFile file : files) {
            fileService.uploadFile(file, null);
        }
        object.put("success",1);
        object.put("result","文件上传成功");
        return object.toString();
    }

在这个 Controller 中使用了 file 数组,如果每次只需要上传一个文件,可以使用单个对象

上传至对象存储服务器

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            <!-- MinIO存储 -->
            <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>8.3.4</version>
                <exclusions>
                    <exclusion>
                        <groupId>com.squareup.okhttp3</groupId>
                        <artifactId>okhttp</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>4.9.3</version>
            </dependency>

官方给出的文档可以直接使用 io.minio:minio 但是我在启动的时候遇到了 okhttp3.RequestBody.create() 方法的两个参数类型是反的的错误,所以只能把低版本的 okhttp 排掉,使用高版本的,高版本的已经解决了这个问题

MinIO 搭建参见 MiniIO 入门教程

配置 Bean

添加配置

1
2
3
4
5
6
# 系统常量配置
oes:
  minio:
    endpoint: http://192.168.1.9:9090
    root-user: minioadmin
    root-password: minioadmin

{: file=’oes-start/src/main/resources/application-dev.yml’}

创建 Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package org.oes.start.tools.minio;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import org.oes.common.constans.OesConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Shiro 配置类
 *
 * @author XuJian
 * @since 2022/01/03
 */
@Configuration(proxyBeanMethods = false)
public class MinioConfig {

    private static final Logger logger = LoggerFactory.getLogger(MinioConfig.class);

    @Value("${oes.minio.endpoint}")
    private String endpoint;
    @Value("${oes.minio.root-user}")
    private String accessKey;
    @Value("${oes.minio.root-password}")
    private String secretKey;

    @Bean
    public MinioClient minioClient() {
        try {
            MinioClient minioClient =  MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(OesConstant.AVATARS_BUCKET).build());
            if(isExist) {
                logger.info("avatar 桶已存在,跳过创建");
            } else {
                // 创建一个名为avatars的存储桶,用于存储照片文件
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(OesConstant.AVATARS_BUCKET).build());
            }
            return  minioClient;
        } catch (Exception e) {
            logger.error("创建 MinioClient 失败", e);
            return null;
        }
    }
}

文件上传服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package org.oes.biz.service.impl;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.oes.biz.service.FileService;
import org.oes.common.exception.OesServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

@Service
public class FileServiceImpl implements FileService {

    private static final Logger logger = LoggerFactory.getLogger(FileService.class);

    @Resource
    private MinioClient minioClient;

    /**
     * 文件上传服务
     *
     * @param file 文件
     * @param fileName 存储文件名(包含目录路径)
     * @param bucket 存储桶
     */
    @Override
    public void uploadFile(MultipartFile file, String fileName, String bucket) {
        try {
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(bucket)
                            .object(fileName)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
        } catch (Exception e) {
            logger.error("上传失败", e);
            throw new OesServiceException("文件上传失败,请尝试重新上传!");
        }
    }
}

此处的服务由于是要提供给 Web 端使用的,所以我直接使用了 MultipartFile 类型传文件,把它转成 ImputStream 再上传

写测试 Controller

1
2
3
4
5
6
7
    @RequestMapping(value = "file/upload", method = RequestMethod.POST)
    public String fileUp(@RequestParam("files") MultipartFile[] files) {
        for (MultipartFile file : files) {
            fileService.uploadFile(file, file.getOriginalFilename(), "test");
        }
        return "文件上传成功";
    }

image-20220110115827882

image-20220110115908856

参考

https://cloud.tencent.com/developer/article/1594124

本文由作者按照 CC BY 4.0 进行授权