springboot整合minio及工具类

文章介绍了如何使用SpringBoot集成Minio进行文件的上传和下载操作,包括配置Minio客户端、编写上传和下载工具类,以及相关异常处理。项目依赖了Minio和OkHttp3库,还包含了Swagger接口文档配置。
摘要由CSDN通过智能技术生成

说明:本文章是springboot和minio的整合,同时还有上传和下载工具类,minio的具体介绍这里就不多说了【上传和下载都是基础工具类, minio的安装如果有时间就更新】

工程图:【主要功能在于工具类,在代码块11和12标红代码

 

1.pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>server-file</groupId>
    <artifactId>server-file</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>server-file Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <!-- swagger -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.9</version>
        </dependency>

        <!--minio 对象存储  -->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.2</version>
        </dependency>

        <!-- 引入 json -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>server-file</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.9.RELEASE</version>
                <configuration>
                    <mainClass>com.file.App</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

2.application.yml 文件

server:
  port: 8080
  servlet:
    context-path: /server-file

minio:
  endpoint: http://127.0.0.1:9000
  accesskey: minioadmin
  secretKey: minioadmin

3.MinioConfiguration.java文件

package com.file.conf;

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MinioConfiguration {


	@Value("${minio.endpoint}")
	private String endpoint;
	@Value("${minio.accesskey}")
	private String accesskey;
	@Value("${minio.secretKey}")
	private String secretKey;

	@Bean
	public MinioClient minioClient() {
		return MinioClient.builder()
				.endpoint(endpoint)
				.credentials(accesskey, secretKey)
				.build();
	}
}

4.SwaggerConfig.java文件

package com.file.conf;

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

import java.util.ArrayList;
import java.util.List;


/**
 * @author 李庆伟
 * @date 2022/5/20 10:22
 */
@ConditionalOnWebApplication
@Configuration
@EnableSwagger2WebMvc
@EnableKnife4j
public class SwaggerConfig {

    /**
     * Swagger2的配置文件,这里可以配置Swagger2的一些基本的内容,比如扫描的包等等
     * []
     * @return {@link Docket}
     * @throws
     * @author 李庆伟
     * @date 2021/12/13 16:28
     */
    @Bean
    public Docket createRestApi() {
        //设置请求在父类方法中,如果在本类方法中设置请求头,则覆盖父类方法
        List<Parameter> pars = makeHeader();
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage(makeScan()))
                //.apis(RequestHandlerSelectors.basePackage(App8300.class.getPackage().getName()))
                .build()
                .globalOperationParameters(pars)
                .apiInfo(apiInfo());
    }

    /**
     * swagger封装请求头
     * [pars]
     * @return {@link List< Parameter>}
     * @throws
     * @author 李庆伟
     * @date 2022/5/20 11:26
     */
    public List<Parameter> makeHeader(){
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder token = new ParameterBuilder();
        token.name("Authorization").description("Authorization")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false).build();
        pars.add(token.build());

        ParameterBuilder languageCode = new ParameterBuilder();
        languageCode.name("languageCode").description("languageCode")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false).build();
        pars.add(languageCode.build());

        return pars;
    }

    public String makeScan(){
        return "com.file.controller";
    }

    /**
     * 构建API文档的详细信息函数
     * @return
     */
    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(makeApiName())
                .version("1.0")
                .build();
    }

    public String makeApiName(){
        return "文档服务接口-API";
    }

}

5.MyException.java文件

package com.file.exceptions;

/**
 * @author 李庆伟
 * @date 2020/4/16 10:10
 */
public class MyException extends RuntimeException{

    private int code;
    private String msg;

    public MyException(int code, String msg){
        super(msg);
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

}

6.TopException.java文件

package com.file.exceptions;

import com.file.results.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author 李庆伟
 * @date 2020/4/16 10:11
 */
@ControllerAdvice
public class TopException {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public Result myExceptionHandle(Exception e){
        MyException myException = (MyException) e;
        return  Result.error(myException.getCode(),myException.getMessage());
    }

    //此异常放在最下面,当所有异常都检查不到的时候会进入该异常
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result handle(Exception e){
        logger.error("系统日志",e);
        return Result.error(1000,"RETURN_FAIL");
    }
}

7.Result.java文件

package com.file.results;

import com.alibaba.fastjson.JSON;
import com.file.util.LanguageUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.servlet.ServletResponse;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author 李庆伟
 * @date 2020/4/16 9:52
 */
@Data
public class Result {

    @ApiModelProperty(value = "返回码")
    private int code;

    @ApiModelProperty(value = "返回数据")
    private Object data;

    @ApiModelProperty(value = "返回描述")
    private String msg;

    @ApiModelProperty(value = "返回长度")
    private long count;

    /**返回成功 */
    public static Result success(List<Object> data, long count){
        Result result = new Result();
        result.setCode(0);//成功
        result.setMsg(LanguageUtil.getMessage("RETURN_SUCCESS"));//提示语
        result.setData(data);
        result.setCount(count);
        return result;
    }

    /**返回成功 */
    public static Result success(List data){
        Result result = new Result();
        result.setCode(0);//成功
        result.setMsg(LanguageUtil.getMessage("RETURN_SUCCESS"));//提示语
        result.setData(data);
        result.setCount(data == null || data.size() == 0 ? 0 : data.size());
        return result;
    }

    /**返回成功 */
    public static Result successForPage(List data, Integer count){
        Result result = new Result();
        result.setCode(0);//成功
        result.setMsg(LanguageUtil.getMessage("RETURN_SUCCESS"));//提示语
        result.setData(data);
        result.setCount(count == null ? 0 : count);
        return result;
    }

    /**返回成功 */
    public static Result success(){
        Result result = new Result();
        result.setCode(0);//成功
        result.setMsg(LanguageUtil.getMessage("RETURN_SUCCESS"));//提示语
        return result;
    }

    /**返回成功 */
    public static Result success(Object object){
        Result result = new Result();
        result.setCode(0);//成功
        result.setMsg(LanguageUtil.getMessage("RETURN_SUCCESS"));//提示语
        result.setData(object);//返回内容
        return result;
    }

    /**返回失败 */
    public static Result error(){
        Result result = new Result();
        result.setCode(1);//失败
        result.setMsg(LanguageUtil.getMessage("RETURN_FAIL"));//提示语
        return result;
    }

    /**返回失败 */
    public static Result error(int code, String msg){
        Result result = new Result();
        result.setCode(code);//失败
        result.setMsg(LanguageUtil.getMessage(msg));//提示语
        return result;
    }


    /**Response输出Json格式 */
    public static void responseJson(ServletResponse response, Object data) {
        PrintWriter out = null;
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json");
            out = response.getWriter();
            out.println(JSON.toJSONString(data));
            out.flush();
        } catch (Exception e) {
            System.out.println("Response输出Json异常:" + e);
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
	/**返回信息*/
	public static Result response(int code, String msg, Object data) {
		Result result = new Result();
		result.setCode(code);
		result.setMsg(msg);
		result.setData(data);
		return result;
	}
}

8.LanguageUtil.java文件

package com.file.util;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

/**
 * 多语言工具类
 * @author 李庆伟
 * @date 2022/5/12 15:57
 */
@Component
public class LanguageUtil {
    private static List<String> languages = Arrays.asList("en-US","fr-FR","zh-CN");
    private static HashMap<String, Properties> mapProperties = new HashMap<>();

    static {
        for(String s:languages){
            mapProperties.put(s,new Properties());
        }
        for(String s:languages){
            String messageConfigFile = String.format("MessageConfig_%s.properties",s);
            InputStream ios = LanguageUtil.class.getClassLoader().getResourceAsStream(messageConfigFile);
            if(ios != null){
                try {
                    mapProperties.get(s).load(ios);
                } catch (IOException e) {
                    throw new RuntimeException("could not find Properties ==> "+ messageConfigFile);
                }finally {
                    try {
                        ios.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 根据key获取.properties文件中的value
     * [key]
     * @return {@link String}
     * @throws
     * @author 李庆伟
     * @date 2022/7/14 10:06
     */
    public static String getMessage(String key){
        //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //language = request.getHeader("languageCode");
        String language = getHeaderLanguages();
        if(StringUtils.isEmpty(language)){
            language = "en-US";
        } else{
            if(!language.equals("fr-FR") && !language.equals("zh-CN")){
                language = "en-US";
            }
        }
        String strMessage = "";
        if(StringUtils.isNotEmpty(key) && mapProperties.get(language) != null){
            strMessage = mapProperties.get(language).getProperty(key);
            if(StringUtils.isEmpty(strMessage)){
                strMessage = key;
            }
        }
        return  strMessage;
    }
	public static String getMessagEn(String key){
		String language = "en-US";
		String strMessage = "";
		if(StringUtils.isNotEmpty(key) && mapProperties.get(language) != null){
			strMessage = mapProperties.get(language).getProperty(key);
			if(StringUtils.isEmpty(strMessage)){
				strMessage = key;
			}
		}
		return  strMessage;
	}
    /**
     * 从请求头中获取多语言类型
     * []
     * @return {@link String}
     * @throws
     * @author 李庆伟
     * @date 2022/7/14 10:04
     */
    public static String getHeaderLanguages(){
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String language = request.getHeader("languageCode");
        return language;
    }


    /**
     * 返回国际化展示字段
     * [chineseName, englishName, frenchName]
     * [name]
     * @return {@link String}
     * @throws
     * @author 李庆伟
     * @date 2022/7/14 10:05
     */
    public static String getDisplayName(String... name) {
        String language = getHeaderLanguages();
        if(StringUtils.isEmpty(language)){
            return name[1];
        }
        switch (language){
            case "en-US":
                return name[1];
            case "fr-FR":
                return name[2];
            case "zh-CN":
                return name[0];
        }
        return name[1];
    }

}

9.App.java文件

package com.file;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

10.UpResModel.java文件

package com.file.model;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * @author 李庆伟
 * @date 2023/2/13 16:51
 */
@Data
public class UpResModel {

    @ApiModelProperty(name = "fileName",value = "文件原始名称")
    private String fileName;

    @ApiModelProperty(name = "filePath",value = "文件内部路径:/桶/文件夹/文件名称")
    private String filePath;

    @ApiModelProperty(name = "visitFilePath",value = "外部访问路径:开发阶段可以自己测试,不可用于线上,有效时间60个小时")
    private String visitFilePath;

}

11.BucketUtil.java文件

package com.file.util;

import com.file.exceptions.MyException;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.RemoveBucketArgs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 桶工具类封装
 * @author 李庆伟
 * @date 2023/2/9 16:39
 */
@Component
public class BucketUtil {

    @Autowired
    private MinioClient client;

    /**
     * 添加桶
     * [client, bucketName]
     * @return {@link }
     * @throws
     * @author 李庆伟
     * @date 2023/2/9 16:44
     */
    public void add(String bucketName) {
        try {
            boolean isExist = exist(bucketName);
            if (!isExist) {
                client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            throw new MyException(1000,"BUCKET_ADD_FAIL");
        }
    }

    /**
     * 删除桶
     * [client, bucketName]
     * @return {@link }
     * @throws
     * @author 李庆伟
     * @date 2023/2/9 16:45
     */
    public void delete(String bucketName) {
        try {
            boolean isExist = exist(bucketName);
            if (isExist) {
                client.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            throw new MyException(1000,"BUCKET_DELETE_FAIL");
        }
    }

    /**
     * 判断桶是否存在
     * [client, bucketName]
     * @return {@link boolean}
     * @throws
     * @author 李庆伟
     * @date 2023/2/9 16:42
     */
    public boolean exist(String bucketName) {
        try {
            return client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

12.FileUtil.java文件

package com.file.util;

import com.file.exceptions.MyException;
import com.file.model.UpResModel;
import com.google.common.io.ByteStreams;
import io.minio.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.lang.StringUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Optional;

/**
 * 文件管理工具类
 *
 * @return {@link }
 * @throws
 * @author 李庆伟
 * @date 2023/2/13 11:40
 */
@Component
public class FileUtil {

    @Autowired
    private MinioClient client;
    /**
     * 上传文件【不带文件夹】
     * [file, bucketName]
     * file:文件
     * bucketName:桶
     * @return {@link Map< String, String>}
     * @throws
     * @author 李庆伟
     * @date 2023/2/10 13:59
     */
    public UpResModel upload(MultipartFile file, String bucketName, String lastName) {
        return upload(file,bucketName,null,lastName);
    }

    /**
     * 上传文件【带文件夹】
     * [client, file, bucketName, folderName]
     * file:文件
     * bucketName:桶
     * folderName:文件夹
     * lastName:
     *          注:因为文件重复覆盖问题,所有的文件上传前都会更改文件名称 即 原来文件名+_+33位随机字符+文件后缀
     *          例如:a.txt 上传后是 a_12....33.txt
     * @return {@link Map< String, String>}
     *  fileName:原始文件名称
     *  filePath:桶+文件夹+文件
     *  visitFilePath:外部访问地址
     * @throws
     * @author 李庆伟
     * @date 2023/2/10 14:00
     */
    public UpResModel upload(MultipartFile file, String bucketName, String folderName, String lastName) {
        //判断桶是否存在
        boolean be = exist(bucketName);
        if(!be){
            throw new MyException(404,"BUCKET_NOT_FIND");
        }
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        folderName = Optional.ofNullable(folderName).orElse("");
        if(!"".equals(folderName)){
            folderName = "/"+ folderName;
        }

        //原始名称
        String fileName = file.getOriginalFilename();

        String minFileName = folderName + "/" + lastName;
        //上传文件到指定目录
        try {
            client.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(minFileName)
                    .contentType(file.getContentType())
                    .stream(inputStream, inputStream.available(), -1)
                    .build());
            inputStream.close();
        } catch (Exception e) {
            throw new MyException(500,"FILE_UPLOAD_FAIL");
        }

        // 返回件访问路径
        /*
        Map<String,String> map = new HashMap<>();
        map.put("fileName",fileName);
        map.put("filePath","/" + bucketName + minFileName);
        map.put("visitFilePath",getObjectUrl(bucketName, minFileName));
        return map;
        */
        UpResModel u = new UpResModel();
        u.setFileName(fileName);
        u.setFilePath("/" + bucketName + minFileName);
        u.setVisitFilePath(getObjectUrl(bucketName, minFileName));
        return u;
    }

    /**
     * 对外连接
     * [client, bucketName, minFileName]
     * bucketName:桶
     * minFileName:文件夹路径+文件名
     * @return {@link String}
     * @throws
     * @author 李庆伟
     * @date 2023/2/10 14:01
     */
    @SneakyThrows
    public String getObjectUrl(String bucketName, String minFileName) {
        //expiry = expiryHandle(expiry);
        return client.getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(minFileName)
                        .expiry(60*60)//过期时间(分钟数)
                        .build()
        );
    }

    /**
     * 单文件下载
     * [client, response, filePath]
     * @return {@link }
     * @throws
     * @author 李庆伟
     * @date 2023/2/13 11:33
     */
    public void download(HttpServletResponse response, String bucketName, String pathName, String downName) {
        if(bucketName == null || pathName == null || downName == null ||
            StringUtils.isEmpty(bucketName) || StringUtils.isEmpty(pathName) || StringUtils.isEmpty(downName)){
            throw new MyException(404,"BUCKET_NOT_FIND");
        }
        try (
                ServletOutputStream os = response.getOutputStream();
                GetObjectResponse is = downloadOne(bucketName, pathName)
        ) {

            response.setCharacterEncoding("utf-8");
            response.setContentType("APPLICATION/OCTET-STREAM");
            response.addHeader("Content-Disposition", "attachment;filename=" + downName);
            ByteStreams.copy(is, os);
            os.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除文件
     * [bucketName, pathName]
     * @return {@link boolean}
     * @throws
     * @author 李庆伟
     * @date 2023/2/13 16:14
     */
    @SneakyThrows
    public boolean deleteFile(String bucketName, String pathName) {
        if (!exist(bucketName)) {
            return false;
        }
        client.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(pathName)
                        .build());
        return true;
    }


    @SneakyThrows
    public GetObjectResponse downloadOne(String bucketName,String objectName) {
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();
        return client.getObject(getObjectArgs);
    }



    public boolean exist(String bucketName) {
        try {
            return client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}

13.BucketController.java文件

package com.file.controller;

import com.file.results.Result;
import com.file.service.BucketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 李庆伟
 * @date 2023/2/9 11:07
 */
@RestController
@RequestMapping("/bucket")
@Api(value = "文件存储桶服务", tags = "文件存储桶服务")
public class BucketController {

    @Autowired
    private BucketService bucketService;

    /**
     * 桶添加
     * @return {@link }
     * @throws
     * @author
     * @date
     */
    @PostMapping(value = "/add")
    @ApiOperation(value = "桶添加", notes = "桶添加", produces = "application/json")
    public Result add(@ApiParam(required = true, value = "bucketName") @RequestParam(value = "bucketName", required = true) String bucketName) {
        bucketService.add(bucketName);
        return Result.success();
    }

    /**
     * 桶删除
     * @return {@link }
     * @throws
     * @author
     * @date
     */
    @PostMapping(value = "/delete")
    @ApiOperation(value = "桶删除", notes = "桶删除", produces = "application/json")
    public Result delete(@ApiParam(required = true, value = "bucketName") @RequestParam(value = "bucketName", required = true) String bucketName) {
        bucketService.delete(bucketName);
        return Result.success();
    }

    /**
     * 桶是否存在
     * @return {@link }
     * @throws
     * @author
     * @date
     */
    @PostMapping(value = "/exist")
    @ApiOperation(value = "桶是否存在", notes = "桶是否存在", produces = "application/json")
    public Result exist(@ApiParam(required = true, value = "bucketName") @RequestParam(value = "bucketName", required = true) String bucketName) {
        return Result.success(bucketService.exist(bucketName));
    }


}

14.BucketService.java文件

package com.file.service;



/**
 *
 * @return {@link }
 * @throws
 * @author
 * @date 2023/2/9 11:28
 */
public interface BucketService {

    //桶添加
    void add(String bucketName);

    //桶删除
    void delete(String bucketName);

    //桶是否存在
    boolean exist(String bucketName);
}

15.BucketServiceImpl.java文件

package com.file.service.impl;

import com.file.service.BucketService;
import com.file.util.BucketUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class BucketServiceImpl implements BucketService {

    @Resource
    private BucketUtil bucketUtil;

    /**
     * 桶添加
     * [bucketName]
     * @return {@link }
     * @throws
     * @date 2023/2/9 11:29
     */
    public void add(String bucketName) {
        bucketUtil.add(bucketName);
    }

    /**
     * 桶删除
     * [bucketName]
     * @return {@link }
     * @throws
     * @date 2023/2/9 11:29
     */
    public void delete(String bucketName) {
        bucketUtil.delete(bucketName);
    }

    /**
     * 桶是否存在
     * [bucketName]
     * @return {@link }
     * @throws
     * @date 2023/2/9 11:29
     */
    public boolean exist(String bucketName) {
        return bucketUtil.exist(bucketName);
    }
}

16.FileController.java文件

package com.file.controller;

import com.file.model.UpResModel;
import com.file.results.Result;
import com.file.service.FileService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author 李庆伟
 * @date 2023/2/9 16:09
 */
@RestController
@RequestMapping("/file")
@Api(value = "文件操作服务", tags = "文件操作服务")
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * 单文件上传
     * [file, bucketName]
     * file:文件流
     * bucketName:桶名称
     * folderName:文件夹路径
     * 例如:上传到桶[tong]下文件夹[/a/b/c]
     * @return {@link Result}
     * @throws
     * @author 李庆伟
     * @date 2023/2/9 16:25
     */
    @PostMapping(value = "/upload")
    @ApiOperation(value = "单文件上传", notes = "单文件上传")
    @ApiResponses({
            @ApiResponse(code = 0, message = "ok", response= UpResModel.class),
    })
    public Result upload(@RequestParam(value = "file") MultipartFile file,
                         @ApiParam(required = true, value = "bucketName") @RequestParam(value = "bucketName", required = true) String bucketName,
                         @ApiParam(required = false, value = "folderName") @RequestParam(value = "folderName", required = false) String folderName
    ){
        UpResModel map = fileService.upload(file, bucketName, folderName);
        //超过5M的文件不进行转换
        return Result.success(map);
    }

    /**
     * 单文件下载
     * [response, filePath]
     * filePath格式:/桶/文件夹1/文件夹2.../文件名称
     *      例如:/tong/a/b/c/d.txt
     * @return {@link }
     * @throws
     * @author 李庆伟
     * @date 2023/2/10 14:39
     */
    @GetMapping("/download")
    @ApiOperation(value = "单文件下载", notes = "单文件下载", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void download(HttpServletResponse response, @ApiParam(required = true, value = "filePath") @RequestParam("filePath")String filePath){
        fileService.download(response,filePath);
    }

    /**
     * 删除文件
     * [filePath]
     * filePath格式:/桶/文件夹1/文件夹2.../文件名称
     *      例如:/tong/a/b/c/d.txt
     * @return {@link Result}
     * @throws
     * @author 李庆伟
     * @date 2023/2/13 15:42
     */
    @DeleteMapping("/delete")
    @ApiOperation(value = "文件删除", notes = "文件删除")
    public Result delete(@ApiParam(required = true, value = "filePath") @RequestParam("filePath")String filePath) {
        return Result.success(fileService.delete(filePath));
    }
}

17.FileService.java文件

package com.file.service;


import com.file.model.UpResModel;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 *
 * @return {@link }
 * @throws
 * @author
 * @date 2023/2/9 11:28
 */
public interface FileService {

    //单文件上传
    UpResModel upload(MultipartFile file, String bucketName, String folderName);

    //单文件下载
    void download(HttpServletResponse response, String fileName);

    //删除文件
    boolean delete(String filePath);
}

18.FileServiceImpl.java文件

package com.file.service.impl;

import com.file.exceptions.MyException;
import com.file.model.UpResModel;
import com.file.service.FileService;
import com.file.util.FileUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService {

    @Resource
    private FileUtil fileUtil;



    /**
     * 单文件上传
     * [file, bucketName]
     * @return {@link Map< String, String>}
     * @throws
     * @author 李庆伟
     * @date 2023/2/9 16:27
     */
    public UpResModel upload(MultipartFile file, String bucketName, String folderName) {
        //原始名称
        String fileName = file.getOriginalFilename();

        int len = fileName.lastIndexOf(".");

        String lastName = "";
        //原始文件名_随机字符串
        if(len != -1){
            lastName = fileName.substring(0,len) + "_" +
                    UUID.randomUUID().toString().replace("-","") +
                    fileName.substring(len,fileName.length());
        } else {
            lastName = fileName+ "_" + UUID.randomUUID().toString().replace("-","");
        }
        UpResModel upResModel = fileUtil.upload(file, bucketName, folderName, lastName);
        return upResModel;
    }

    /**
     * 单文件下载
     * [response, fileName]
     * @return {@link }
     * @throws
     * @author 李庆伟
     * @date 2023/2/10 14:40
     */
    public void download(HttpServletResponse response,final String filePath) {
        if(filePath == null || StringUtils.isEmpty(filePath)){
            throw new MyException(404,"BUCKET_NOT_FIND");
        }

        String bucketName = filePath.split("/")[1];
        String pathName = filePath.replace("/"+bucketName,"");

        String fileName = "";
        String [] arr = filePath.split("/");
        String name = arr[arr.length-1];
        int m = name.lastIndexOf("_");
        int n = name.lastIndexOf(".");
        if(m != -1 && n != -1 && n-m == 33){
            String prefixName = name.substring(0,m);
            String suffixName = name.substring(n,name.length());
            fileName = prefixName+suffixName;
        } else if (m != -1 && n == -1 && name.substring(m,name.length()).length() == 33){
            fileName = name.substring(0,m);
        } else {
            fileName = name;
        }
        fileUtil.download(response,bucketName,pathName,fileName);

    }

    /**
     * 删除文件
     * [filePath]
     * @return {@link boolean}
     * @throws
     * @author 李庆伟
     * @date 2023/2/13 15:43
     */
    @SneakyThrows
    public boolean delete(String filePath) {
        String bucketName = filePath.split("/")[1];
        String pathName = filePath.replace("/"+bucketName,"");
        return fileUtil.deleteFile(bucketName,pathName);
    }


}

19.MessageConfig_zh-CN.properties,MessageConfig_en-US.properties,MessageConfig_fr-FR.properties文件 三个文件中的内容都一样

#public

RETURN_SUCCESS = 成功!

RETURN_FAIL = 失败!

BUCKET_NOT_FIND = 桶不存在.

FILE_UPLOAD_FAIL = 文件上传失败.

内容比较简单,到此结束。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值