springboot整合minio及工具类

news2024/9/20 15:38:59

说明:本文章是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 = 文件上传失败.

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/383851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

好意外,发现永久免费使用的云服务器

原因就不说了&#xff0c;说一下过程&#xff0c;在百度搜pythonIDE的时候&#xff0c;发现了一个网站 https://lightly.teamcode.com/https://lightly.teamcode.com/ 就是这个网站&#xff0c;看见这个免费试用&#xff0c;一开始觉得没什么&#xff0c;在尝试使用的过程中发…

IIC总线式驱动开发(mpu6050)(二)

目录 六、I2C总线二级外设驱动开发方法 七、I2C总线二级外设驱动开发之名称匹配 1. i2c_register_board_info 2. i2c_new_device&#xff1a;明确二级外设地址的情况下可用 3. i2c_new_probed_device 八、I2C总线二级外设驱动开发之设备树匹配 六、I2C总线二级外设驱动开…

AVL树(Insert)

文章目录AVL树代码模拟实现Insert重点控制平衡:旋转->平衡右单旋左单旋左右双旋双旋平衡因子更新错误右左双旋左右双旋erase了解AVL树的性能AVL树 代码 高度平衡二叉搜索树 引入 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单…

C/C++网络编程笔记Socket

https://www.bilibili.com/video/BV11Z4y157RY/?vd_sourced0030c72c95e04a14c5614c1c0e6159b上面链接是B站的博主教程&#xff0c;源代码来自上面视频&#xff0c;侵删&#xff0c;这里只是做笔记&#xff0c;以供复习和分享。上一篇博客我记录了配置环境并且跑通了&#xff0…

从头开始搭建一个SpringBoot项目--SpringBoot文件的上传与下载

从头开始搭建一个SpringBoot项目--SpringBoot文件的上传前言流程分析代码结构代码详情UploadFileInfo.classUploadController.classUploadDao.classUploadDao.xmlUploadServices.classUploadServicesImpl.class测试下载示例前言 文件的上传和下载是很多系统必备的功能&#xf…

pytorch-复现经典深度学习模型-LeNet5

Neural Networks 使用torch.nn包来构建神经网络。nn包依赖autograd包来定义模型并求导。 一个nn.Module包含各个层和一个forward(input)方法&#xff0c;该方法返回output。 一个简单的前馈神经网络&#xff0c;它接受一个输入&#xff0c;然后一层接着一层地传递&#xff0c;…

代码随想录算法训练营day47 |动态规划 198打家劫舍 213打家劫舍II 337打家劫舍III

day47198.打家劫舍1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组213.打家劫舍II情况一&#xff1a;考虑不包含首尾元素情况二&#xff1a;考虑包含首元素&#xff0c;不包含尾元素情况三&#x…

网络技术|网络地址转换与IPv6|路由设计基础|4

对应讲义——p6 p7NAT例题例1解1例2解2例3解3例4解4一、IPv6地址用二进制格式表示128位的一个IPv6地址&#xff0c;按每16位为一个位段&#xff0c;划分为8个位段。若某个IPv6地址中出现多个连续的二进制0&#xff0c;可以通过压缩某个位段中的前导0来简化IPv6地址的表示。例如…

1月奶粉电商销售数据榜单:销售额约20亿,高端化趋势明显

鲸参谋电商数据监测的2023年1月份京东平台“奶粉”品类销售数据榜单出炉&#xff01; 根据鲸参谋数据显示&#xff0c;1月份京东平台上奶粉的销量约675万件&#xff0c;销售额约20亿元&#xff0c;环比均下降19%左右。与去年相比&#xff0c;整体也下滑了近34%。可以看出&#…

真无线耳机哪个牌子好用?2023便宜好用的无线耳机推荐

蓝牙耳机经过近几年的快速发展&#xff0c;变得越来越普及&#xff0c;并且在一些性能上也做得越来越好。那么&#xff0c;真无线耳机哪个牌子好用&#xff1f;下面&#xff0c;我来给大家推荐几款便宜好用的无线耳机&#xff0c;可以参考一下。 一、南卡小音舱蓝牙耳机 参考…

Nuxt 3.0 全栈开发:五种渲染模式的差异和使用场景全解析

Nuxt 3.0 全栈开发 - 杨村长 - 掘金小册核心知识 工程架构 全栈进阶 项目实战&#xff0c;快速精通 Nuxt3 开发&#xff01;。「Nuxt 3.0 全栈开发」由杨村长撰写&#xff0c;299人购买https://s.juejin.cn/ds/S6p7MVo/ 前面我们提到过 Nuxt 能够满足我们更多开发场景的需求…

IGKBoard(imx6ull)-I2C接口编程之SHT20温湿度采样

文章目录1- 使能开发板I2C通信接口2- SHT20硬件连接3- 编码实现SHT20温湿度采样思路&#xff08;1&#xff09;查看sht20从设备地址&#xff08;i2cdetect&#xff09;&#xff08;2&#xff09;获取数据大体流程【1】软复位【2】触发测量与通讯时序&#xff08;3&#xff09;返…

日志收集笔记(Kibana,Watcher)

1 Kibana Kibana 是一个开源的分析与可视化平台&#xff0c;可以用 Kibana 搜索、查看存放在 Elasticsearch 中的数据&#xff0c;就跟谷歌的 elasticsearch head 插件类似&#xff0c;但 Kibana 与 Elasticsearch 的交互方式是各种不同的图表、表格、地图等&#xff0c;直观的…

【python】控制台中文输出乱码解决方案

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录控制台原因解决方法方法一方法二方法三如果是os.system函数乱码控制台原因 一般的情况下&#xff0c;还是我们的源码文件的编码格式问题。我们一般是要把源码文件的编码格式改成utf-8就好了&#xff0c;但是…

zeppelin安装及hive配置

一、zeppelin安装包 链接&#xff1a;https://pan.baidu.com/s/1DVmvY2TM7WmCskejTn8dzA 提取码&#xff1a;fl7r 二、安装zeppelin 将安装包传入Centos的/opt/install目录下 # 解压 tar -zxf /opt/install/zeppelin-0.10.0-bin-all.tgz -C /opt/soft/ # 重命名 mv /opt/sof…

Nodejs环境配置 | Linux安装nvm | windows安装nvm

文章目录一. 前言二. Linux Nodejs环境配置1. 安装nvm2. 配置npm三. Windows Nodejs环境配置1. 安装nvm2. 配置npm四. nvm基本使用一. 前言 由于在实际开发中一些不同的项目需要不同的npm版本来启动&#xff0c;所以本篇文章会基于nvm这个node版本管理工具来进行Linux和Winodw…

[AI助力] 2022.3.2 考研英语学习 2011 英语二翻译

[AI助力] 2022.3.2 考研英语学习 2011 英语二翻译 文章目录[AI助力] 2022.3.2 考研英语学习 2011 英语二翻译2011年英语二翻译真题自己写的看看AI的翻译谷歌翻译New Bing&#x1f602;让AI自我评价chatgpt&#x1f923;让AI自我评价DeepL有道腾讯翻译百度翻译IDEA翻译积累&…

智能家居项目(八)之树莓派+摄像头进行人脸识别

目录 1、编辑Camera.c 2、编辑contrlDevices.h 3、编辑mainPro.c 4、进行编译&#xff1a; 5、运行结果&#xff1a; ./test1 6、项目图片演示 智能家居项目&#xff08;七&#xff09;之Libcurl库与HTTPS协议实现人脸识别_Love小羽的博客-CSDN博客 经过上一篇文章&…

redhawk:Low Power Analysis

1.rush current与switch cell 在standby状态下为了控制leakage power我们选择power gating的设计方式&#xff0c;使用power switch cell关闭block/power domain的电源。 power switch的基本介绍可见: 低功耗设计-Power Switch power switch的table中有四种状态&#xff0c;…

Simulink 自动代码生成电机控制:优化Simulink生成的代码提升代码运行效率

目录 优化需求 优化方法 从模型配置优化 优化结果对比 从算法层优化 优化结果对比 总结 优化需求 本次优化的目的是提升FOC代码执行速度&#xff0c;以普通滑模观测器为例&#xff0c;优化前把速度环控制放到2ms的周期单独运行&#xff0c;把VOFA上位机通信代码放到主循…