第三章:minio的javaAPI

官方的Java demo:https://github.com/minio/minio-java

章节快捷访问:

第一章:minio介绍与安装

第一章:minio介绍与安装_BUG胡汉三的博客-CSDN博客_minio介绍

第二章:minio单机版,使用客户端备份文件

第二章:minio单机版,使用客户端备份文件_BUG胡汉三的博客-CSDN博客_minio 备份

第三章:minio的javaAPI

第三章:minio的javaAPI_BUG胡汉三的博客-CSDN博客_minio获取文件大小

第四章:minio的presigned URLs上传文件

第四章:minio的presigned URLs上传文件_BUG胡汉三的博客-CSDN博客_minio 临时上传

--------------------------------------------------

在之前我们已经把minio的服务端,客户端,以及镜像备份都做好了,现在我们来试试通过java的API来操作minio。

环境是Spring boot的

版本是2.1.4.RELEASE

参照官方的API文档:MinIO | Java Client Quickstart Guide

配置

首先我们先引入minio的maven配置:

<!--  minio配置  -->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>3.0.10</version>
</dependency>

在配置一下minio的地址,用户名跟密码等:

minio:
  endpoint: http://192.168.51.78:9001
  accessKey: username
  secretKey: password
  # 下载地址
  http-url: http://127.0.0.1:8080/plat/admin_api/files/url
  imgSize: 10485760
  fileSize: 104857600

java代码

首先,先使用一个实体类接收minio的配置信息

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 读取文件的配置
 * @author 胡汉三
 * @time 2020/5/12 10:14
 */
@Component
@Data
@ConfigurationProperties("minio")
public class FilesConfig {

    /**minio的路径**/
    private String endpoint;

    /**minio的accessKey**/
    private String accessKey;

    /**minio的secretKey**/
    private String secretKey;
    
    /**下载地址**/
    private String httpUrl;

    /**图片大小限制**/
    private Long imgSize;
    
    /**文件大小限制**/
    private Long fileSize;
}

接着再是写一个minio的操作模版类

import com.ktwlsoft.framework.files.config.FilesConfig;
import com.ktwlsoft.framework.files.vo.MinioItem;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.Result;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Minio模板类
 * @author 胡汉三
 * @time 2020/5/12 11:28
 */
@Component
@RequiredArgsConstructor
public class MinioTemplate implements InitializingBean {
    @Autowired
    private FilesConfig filesConfig;
    private MinioClient client;

    /**
     * 检查文件存储桶是否存在
     * @param bucketName
     * @return
     */
    @SneakyThrows
    public boolean bucketExists(String bucketName){
        return client.bucketExists(bucketName);
    }

    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void createBucket(String bucketName) {
        if (!bucketExists(bucketName)) {
            client.makeBucket(bucketName);
        }
    }

    /**
     * 获取全部bucket
     * <p>
     * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
     */
    @SneakyThrows
    public List<Bucket> getAllBuckets() {
        return client.listBuckets();
    }

    /**
     * 根据bucketName获取信息
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public Optional<Bucket> getBucket(String bucketName) {
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /**
     * 根据bucketName删除信息
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void removeBucket(String bucketName) {
        client.removeBucket(bucketName);
    }

    /**
     * 根据文件前缀查询文件
     *
     * @param bucketName bucket名称
     * @param prefix     前缀
     * @param recursive  是否递归查询
     * @return MinioItem 列表
     */
    @SneakyThrows
    public List<MinioItem> getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
        List<MinioItem> objectList = new ArrayList<>();
        Iterable<Result<Item>> objectsIterator = client.listObjects(bucketName, prefix, recursive);
        for (Result<Item> result : objectsIterator) {
            objectList.add(new MinioItem(result.get()));
        }
        return objectList;
    }

    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param expires    过期时间 <=7
     * @return url
     */
    @SneakyThrows
    public String getObjectURL(String bucketName, String objectName, Integer expires) {
        return client.presignedGetObject(bucketName, objectName, expires);
    }

    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return url
     */
    @SneakyThrows
    public String getObjectURL(String bucketName, String objectName) {
        return client.presignedGetObject(bucketName, objectName);
    }

    /**
     * 获取文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return 二进制流
     */
    @SneakyThrows
    public InputStream getObject(String bucketName, String objectName) {
        return client.getObject(bucketName, objectName);
    }

    /**
     * 上传文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param stream     文件流
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream) throws Exception {
        client.putObject(bucketName, objectName, stream, stream.available(), "application/octet-stream");
    }

    /**
     * 上传文件
     *
     * @param bucketName  bucket名称
     * @param objectName  文件名称
     * @param stream      文件流
     * @param size        大小
     * @param contextType 类型
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
        client.putObject(bucketName, objectName, stream, size, contextType);
    }

    /**
     * 获取文件信息
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
     */
    public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {
        return client.statObject(bucketName, objectName);
    }

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
     */
    public void removeObject(String bucketName, String objectName) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InternalException, NoResponseException, InvalidBucketNameException, XmlPullParserException, ErrorResponseException {
        client.removeObject(bucketName, objectName);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.client = new MinioClient(filesConfig.getEndpoint(), filesConfig.getAccessKey(), filesConfig.getSecretKey());
    }
}

MinioItem实体

import io.minio.messages.Item;
import io.minio.messages.Owner;
import io.swagger.annotations.ApiModelProperty;

import java.util.Date;

/**
 * 文件对象
 * @author 胡汉三
 * @time 2019/8/29 14:53
 */
public class MinioItem {
    /**对象名称**/
    @ApiModelProperty("对象名称")
    private String objectName;
    /**最后操作时间**/
    @ApiModelProperty("最后操作时间")
    private Date lastModified;
    private String etag;
    /**对象大小**/
    @ApiModelProperty("对象大小")
    private String size;
    private String storageClass;
    private Owner owner;
    /**对象类型:directory(目录)或file(文件)**/
    @ApiModelProperty("对象类型:directory(目录)或file(文件)")
    private String type;

    public MinioItem(String objectName, Date lastModified, String etag, String size, String storageClass, Owner owner, String type) {
        this.objectName = objectName;
        this.lastModified = lastModified;
        this.etag = etag;
        this.size = size;
        this.storageClass = storageClass;
        this.owner = owner;
        this.type = type;
    }


    public MinioItem(Item item) {
        this.objectName = item.objectName();
        this.type = item.isDir() ? "directory" : "file";
        this.etag = item.etag();
        long sizeNum = item.objectSize();
        this.size = sizeNum > 0 ? convertFileSize(sizeNum):"0";
        this.storageClass = item.storageClass();
        this.owner = item.owner();
        try {
            this.lastModified = item.lastModified();
        }catch(NullPointerException e){}
    }

    public String getObjectName() {
        return objectName;
    }

    public void setObjectName(String objectName) {
        this.objectName = objectName;
    }

    public Date getLastModified() {
        return lastModified;
    }

    public void setLastModified(Date lastModified) {
        this.lastModified = lastModified;
    }

    public String getEtag() {
        return etag;
    }

    public void setEtag(String etag) {
        this.etag = etag;
    }

    public String getSize() {
        return size;
    }

    public void setSize(String size) {
        this.size = size;
    }

    public String getStorageClass() {
        return storageClass;
    }

    public void setStorageClass(String storageClass) {
        this.storageClass = storageClass;
    }

    public Owner getOwner() {
        return owner;
    }

    public void setOwner(Owner owner) {
        this.owner = owner;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String convertFileSize(long size) {
        long kb = 1024;
        long mb = kb * 1024;
        long gb = mb * 1024;
        if (size >= gb) {
            return String.format("%.1f GB", (float) size / gb);
        } else if (size >= mb) {
            float f = (float) size / mb;
            return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
        } else if (size >= kb) {
            float f = (float) size / kb;
            return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
        } else{
            return String.format("%d B", size);
        }
    }
}

接下来写一个对外的http上传接口

import com.google.api.client.util.Lists;
import com.ktwlsoft.framework.files.config.FilesConfig;
import com.ktwlsoft.framework.files.service.impl.MinioTemplate;
import com.ktwlsoft.framework.files.util.BaseConstant;
import com.ktwlsoft.framework.files.util.BucketNameConfig;
import com.ktwlsoft.framework.files.vo.UpLoadResult;
import com.ktwlsoft.framework.common.MvcController;
import com.ktwlsoft.framework.common.result.ActionResult;
import com.ktwlsoft.framework.common.result.ResultCode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 文件上传
 * @author 胡汉三
 * @time 2020/5/12 12:37
 */
@Api(value = "文件上传", description = "文件上传接口", hidden = true)
@RestController
@RequestMapping(BaseConstant.PREFIX_AUTH+"/upload")
public class UploadFilesController extends MvcController {

    private Log log = LogFactory.getLog(UploadFilesController.class);
    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private FilesConfig config;

    /**
     * 上传文件
     * @param upfile        上传的文件对象
     * @param bucketName    所属的存储桶(第一级目录)
     * @param perfixName    文件对象前缀名称
     * @param expires       外链过期时间
     * @return
     */
    @ApiOperation(value = "上传文件" , response = UpLoadResult.class)
    @PostMapping("file")
    public ActionResult<Object> upload(@ApiParam(name = "upfile",value = "文件参数名称") @RequestParam("upfile") MultipartFile upfile,
                                             @ApiParam(name = "bucketName",value = "文件桶名称") String bucketName,
                                             @ApiParam(name = "perfixName",value = "文件对象前缀名称") String perfixName,
                                             @ApiParam(name = "expires",value = "链接过期时间") Integer expires,
                                             @ApiParam(name = "dateFile",value = "是否需要创建时间文件夹:1是,其它否") Integer dateFile) {
        String fileName = upfile.getOriginalFilename();
        try {
            fileCheck(upfile,fileName);
        } catch (Exception e) {
            return error(ResultCode.DATA_INPUT_ERROR.getValue(),e.getMessage());
        }
        if(StringUtils.isBlank(bucketName)){
            return error(ResultCode.DATA_INPUT_EMPTY);
        }
        if(StringUtils.isBlank(fileName)){
            return error(ResultCode.DATA_INPUT_EMPTY);
        }
        StringBuilder sbFile = new StringBuilder();
        if(StringUtils.isNotBlank(perfixName)){
            sbFile.append(perfixName).append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        if(dateFile != null && dateFile == 1){
            // 创建时间文件夹
            sbFile.append(BucketNameConfig.getYear());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
            sbFile.append(BucketNameConfig.getMonthAndDay());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        sbFile.append(fileName);
        fileName = sbFile.toString();
        try {
            minioTemplate.createBucket(bucketName);
            minioTemplate.putObject(bucketName, fileName, upfile.getInputStream());

            UpLoadResult result = new UpLoadResult();
            if(expires == null){
                expires = BaseConstant.ONE_DAY;
            }
            result.setFileUrl(config.getHttpUrl()+"?bucketName="+bucketName+"&objectName="+fileName+"&expires="+expires);
            result.setBucketName(bucketName);
            result.setObjectName(fileName);
            return success(result);
        } catch (Exception e) {
            log.error("文件上传异常", e);
            ResultCode code =  ResultCode.FILE_SAVE_ERROR;
            return error(code);
        }
    }


    /**
     * 多上传文件
     * @param upfileList    上传的文件对象集合
     * @param bucketName    所属的存储桶(第一级目录)
     * @param expires       外链过期时间
     * @return
     */
    @ApiOperation(value = "多上传文件" , response = UpLoadResult.class)
    @PostMapping("fileList")
    public ActionResult<Object> uploadList(@ApiParam(name = "upfileList",value = "文件集合参数名称") @RequestParam("upfileList") List<MultipartFile> upfileList,
                                       @ApiParam(name = "bucketName",value = "文件桶名称") String bucketName,
                                           @ApiParam(name = "perfixName",value = "文件前缀名称") String perfixName,
                                       @ApiParam(name = "expires",value = "链接过期时间") Integer expires,
                                        @ApiParam(name = "dateFile",value = "是否需要创建时间文件夹:1是,其它否") Integer dateFile) {
        if(StringUtils.isBlank(bucketName)){
            return error(ResultCode.DATA_INPUT_EMPTY);
        }
        List<UpLoadResult> resultList = Lists.newArrayList();
        StringBuilder sbFile = new StringBuilder();
        if(StringUtils.isNotBlank(perfixName)){
            sbFile.append(perfixName).append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        if(dateFile != null && dateFile == 1){
            // 创建时间文件夹
            sbFile.append(BucketNameConfig.getYear());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
            sbFile.append(BucketNameConfig.getMonthAndDay());
            sbFile.append(BucketNameConfig.FILE_SPLIT_PATH);
        }
        for (MultipartFile file:upfileList) {
            String fileName = file.getOriginalFilename();
            try {
                fileCheck(file,fileName);
            } catch (Exception e) {
                return error(ResultCode.DATA_INPUT_ERROR.getValue(),e.getMessage());
            }
            fileName = sbFile.toString()+fileName;
            try {
                minioTemplate.createBucket(bucketName);
                minioTemplate.putObject(bucketName, fileName, file.getInputStream());
                UpLoadResult result = new UpLoadResult();
                if(expires == null){
                    expires = BaseConstant.ONE_DAY;
                }
                result.setFileUrl(config.getHttpUrl()+"?bucketName="+bucketName+"&objectName="+fileName+"&expires="+expires);
                result.setBucketName(bucketName);
                result.setObjectName(fileName);
                resultList.add(result);
            } catch (Exception e) {
                log.error("文件上传异常", e);
                ResultCode code =  ResultCode.FILE_SAVE_ERROR;
                return error(code);
            }
        }
        return success(resultList);
    }


    /**
     * 判断是否图片
     */
    private boolean isImage(String fileName) {
        //设置允许上传文件类型
        String suffixList = "jpg,gif,png,ico,bmp,jpeg";
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf(".")
                + 1, fileName.length());
        if (suffixList.contains(suffix.trim().toLowerCase())) {
            return true;
        }
        return false;
    }

    /**
     * 验证文件大小
     * @param upfile
     * @param fileName  文件名称
     * @throws Exception
     */
    private void fileCheck(MultipartFile upfile,String fileName) throws Exception {
        Long size = upfile.getSize();
        if(isImage(fileName)){
            if(size > config.getImgSize()){
                throw new Exception("上传对图片大于:"+(config.getImgSize() / 1024 / 1024) +"M限制");
            }
        }else{
            if(size > config.getFileSize()){
                throw new Exception("上传对文件大于:"+(config.getFileSize() / 1024 / 1024) +"M限制");
            }
        }
    }
}

下载

大家可能会疑惑,这个httpUrl的配置是什么鬼,这个就是文件的下载地址了,因为我们上传了文件过后,总要返回一个下载地址回去给别人做存储。而且要永久有效的连接。但是minio有一个功能是生成可以设置过期时间的外链。所以我们这里就做一个中转,让应用来访问我们的接口,我们来调用minio生成可访问的链接。

有过期时间的外链

/**
 * 获取文件外链
 * @param bucketName        文件桶名称
 * @param objectName        文件对象名称
 * @param expires           外链有效时间(单位:秒)
 * @return
 */
@ApiOperation(value = "获取文件外链", response = ActionResult.class)
@GetMapping("/url")
public ModelAndView getObjectUrl(@ApiParam(name = "bucketName",value = "文件桶名称")String bucketName,
                                 @ApiParam(name = "objectName",value = "文件对象名称") String objectName,
                                 @ApiParam(name = "bucketName",value = "外链有效时间(单位:秒)")Integer expires) throws IOException, XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, InvalidPortException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InvalidEndpointException, InternalException, InvalidExpiresRangeException {
    //ModelAndView model = new ModelAndView();
    if(StringUtils.isBlank(bucketName)){
        return null;
    }
    if(StringUtils.isBlank(objectName)){
        return null;
    }
    if(expires == null){
        expires = BaseConstant.ONE_DAY;
    }
    String utl = template.getObjectURL(bucketName, objectName, expires);
    if(StringUtils.isBlank(utl)){
        return null;
    }
    return  new ModelAndView(new RedirectView(utl));
}

永久有效的外链

我没有在java的API中找到可以设置永久有效的外链设置。但是可以在客户端中设置某个文件桶的内容的下载策略

mc policy public minio80/staticFile

意思就是设置minio80文件桶的staticFile文件桶为开放管理,可以通过url直接下载

【桶名称】/【路径】一路直接到要下载的文件

下载文件

/**
 * 文件流下载
 * @param bucketName    文件桶名称
 * @param objectName    文件对象名称
 * @param response
 * @param request
 */
@ApiOperation(value = "文件流下载", response = ActionResult.class)
@GetMapping("/io/{bucketName}/{objectName}/")
public void downloadIo(@ApiParam(name = "bucketName",value = "文件桶名称") @PathVariable String bucketName,
                       @ApiParam(name = "objectName",value = "文件对象名称") @PathVariable String objectName, HttpServletResponse response, HttpServletRequest request){
    javax.servlet.ServletOutputStream out = null;
    try (InputStream inputStream = template.getObject(bucketName,objectName)) {
        response.setHeader("Content-Disposition", "attachment;filename=" + objectName.substring(objectName.lastIndexOf("/")+1));
        response.setContentType("application/force-download");
        response.setCharacterEncoding("UTF-8");
        out = response.getOutputStream();
        byte[] content = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(content)) != -1) {
            out.write(content, 0, length);
        }
        out.flush();
    } catch (Exception e) {
        log.error("文件读取异常", e);
    }finally {
        if(out != null){
            try {
                out.close();
            } catch (IOException e) {
                log.error("文件流关闭异常", e);
            }
        }
    }
}

完整的控制器代码

import com.github.pagehelper.PageInfo;
import com.ktwlsoft.framework.files.service.impl.MinioTemplate;
import com.ktwlsoft.framework.files.util.BaseConstant;
import com.ktwlsoft.framework.files.vo.MinioItem;
import com.ktwlsoft.framework.common.MvcController;
import com.ktwlsoft.framework.common.result.ActionResult;
import com.ktwlsoft.framework.common.result.ResultCode;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.xmlpull.v1.XmlPullParserException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件对象控制器
 * @author 胡汉三
 * @time 2020/5/12 14:49
 */
@Api(value = "文件对象操作", description = "文件对象操作接口", hidden = true)
@RestController
@RequestMapping(BaseConstant.PREFIX_AUTH+"/files")
public class FilesController extends MvcController {

    /**日志对象**/
    private Log log = LogFactory.getLog(FilesController.class);

    /**Minio模板类注入**/
    @Autowired
    private MinioTemplate template;

    /**
     * 根据文件前缀查询文件
     * @param bucketName    文件桶名称
     * @param objectName    文件对象名称
     * @return
     * @throws InvalidPortException
     * @throws InvalidEndpointException
     */
    @ApiOperation(value = "根据文件前缀查询文件", response = ActionResult.class)
    @GetMapping("/prefix/list")
    public ActionResult<Object> filterObject(@ApiParam(name = "bucketName",value = "文件桶名称")String bucketName,
                                             @ApiParam(name = "objectName",value = "文件对象名称")String objectName) throws InvalidPortException, InvalidEndpointException {
        if(StringUtils.isBlank(bucketName)){
            return error(ResultCode.DATA_INPUT_EMPTY.getValue(),"文件桶名称不能为空");
        }
        List<MinioItem> list = template.getAllObjectsByPrefix(bucketName, objectName, false);
        PageInfo<MinioItem> pageInfo = new PageInfo<>();
        pageInfo.setTotal(list.size());
        pageInfo.setPageSize(10000);
        pageInfo.setList(list);
        return success(pageInfo);
    }

    /**
     * 获取文件外链
     * @param bucketName        文件桶名称
     * @param objectName        文件对象名称
     * @param expires           外链有效时间(单位:秒)
     * @return
     */
    @ApiOperation(value = "获取文件外链", response = ActionResult.class)
    @GetMapping("/{bucketName}/{objectName}/{expires}/")
    public ActionResult<Object> getObject( @ApiParam(name = "bucketName",value = "文件桶名称") @PathVariable String bucketName,
                                           @ApiParam(name = "objectName",value = "文件对象名称") @PathVariable String objectName,
                                           @ApiParam(name = "bucketName",value = "外链有效时间(单位:秒)") @PathVariable Integer expires) throws IOException, XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, InvalidPortException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InvalidEndpointException, InternalException, InvalidExpiresRangeException {
        Map<String,Object> responseBody = new HashMap<>(4);
        // Put Object info
        responseBody.put("bucket" , bucketName);
        responseBody.put("object" , objectName);
        if(expires <= 0){
            expires = BaseConstant.ONE_DAY;
        }
        responseBody.put("url" , template.getObjectURL(bucketName, objectName, expires));
        responseBody.put("expires" ,  expires);
        return success(responseBody);
    }

    /**
     * 获取文件外链
     * @param bucketName        文件桶名称
     * @param objectName        文件对象名称
     * @param expires           外链有效时间(单位:秒)
     * @return
     */
    @ApiOperation(value = "获取文件外链", response = ActionResult.class)
    @GetMapping("/url")
    public ModelAndView getObjectUrl(@ApiParam(name = "bucketName",value = "文件桶名称")String bucketName,
                                     @ApiParam(name = "objectName",value = "文件对象名称") String objectName,
                                     @ApiParam(name = "bucketName",value = "外链有效时间(单位:秒)")Integer expires) throws IOException, XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, InvalidPortException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InvalidEndpointException, InternalException, InvalidExpiresRangeException {
        //ModelAndView model = new ModelAndView();
        if(StringUtils.isBlank(bucketName)){
            return null;
        }
        if(StringUtils.isBlank(objectName)){
            return null;
        }
        if(expires == null){
            expires = BaseConstant.ONE_DAY;
        }
        String utl = template.getObjectURL(bucketName, objectName, expires);
        if(StringUtils.isBlank(utl)){
            return null;
        }
        return  new ModelAndView(new RedirectView(utl));
    }

    /**
     * 文件流下载
     * @param bucketName    文件桶名称
     * @param objectName    文件对象名称
     * @param response
     * @param request
     */
    @ApiOperation(value = "文件流下载", response = ActionResult.class)
    @GetMapping("/io/{bucketName}/{objectName}/")
    public void downloadIo(@ApiParam(name = "bucketName",value = "文件桶名称") @PathVariable String bucketName,
                           @ApiParam(name = "objectName",value = "文件对象名称") @PathVariable String objectName, HttpServletResponse response, HttpServletRequest request){
        javax.servlet.ServletOutputStream out = null;
        try (InputStream inputStream = template.getObject(bucketName,objectName)) {
            response.setHeader("Content-Disposition", "attachment;filename=" + objectName.substring(objectName.lastIndexOf("/")+1));
            response.setContentType("application/force-download");
            response.setCharacterEncoding("UTF-8");
            out = response.getOutputStream();
            byte[] content = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(content)) != -1) {
                out.write(content, 0, length);
            }
            out.flush();
        } catch (Exception e) {
            log.error("文件读取异常", e);
        }finally {
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    log.error("文件流关闭异常", e);
                }
            }
        }
    }

    /**
     * 删除文件对象
     * @param bucketName    文件桶名称
     * @param objectName    文件对象名称:(pdf/2020/0510/test.pdf)
     */
    @ApiOperation(value = "删除文件对象", response = ActionResult.class)
    @DeleteMapping("/{bucketName}/{objectName}/")
    public ActionResult<Object> deleteObject(
            @ApiParam(name = "bucketName",value = "文件桶名称") @PathVariable String bucketName,
            @ApiParam(name = "objectName",value = "文件对象名称:(pdf/2020/0510/test.pdf)") @PathVariable String objectName)
            throws IOException, XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, InvalidPortException, ErrorResponseException, NoResponseException, InvalidBucketNameException, InsufficientDataException, InternalException{
        template.removeObject(bucketName, objectName);
        return success(null,"删除成功");
    }
}

-------------------------------------新增BucketNameConfig-------------------------------------------

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 文件夹(桶bucket)名称创建器
 * @author 胡汉三
 * @time 2019/8/29 11:50
 */
public class BucketNameConfig {

    /**minion文档目录分割符**/
    public static final String FILE_SPLIT_PATH = "/";
    /**时间格式化格式**/
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * 获得当前时间:年(格式:yyyy)
     * @return
     */
    public static int getYear(){
        return LocalDate.now().getYear();
    }

    /**
     * 获得当前时间:月(格式:MM)
     * @return
     */
    public static String getMonth(){
        int month = LocalDate.now().getMonth().getValue();
        if(month < 10){
            return "0"+month;
        }
        return Integer.valueOf(month).toString();
    }

    /**
     * 获得当前时间:日(格式:dd)
     * @return
     */
    public static String getDay(){
        int day = LocalDate.now().getDayOfMonth();
        if(day < 10){
            return "0"+day;
        }
        return Integer.valueOf(day).toString();
    }

    /**
     * 获得当前时间(格式:yyyyMMdd)
     * @return
     */
    public static String getFullDay(){
        return LocalDate.now().format(DATE_FORMATTER);
    }

    /**
     * 获得当前时间月和日(格式:MMdd)
     * @return
     */
    public static String getMonthAndDay(){
        return getMonth()+getDay();
    }
}

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BUG胡汉三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值