七牛云文件上传

七牛云文件上传

接收文件的Base64字符串,并上传到七牛云存储中。

使用SpringBoot框架,所有配置都配置在配置文件中,使用实体类的方式获取配置。

application.yml

#七牛云配置
qiniu:
  ak: xxx
  sk: xxx
  #桶
  bucket-default: xxx
  #图片服务器地址
  domain: xxx

获取配置的实体

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

/**
 * @className QiniuConfig
 * @description 七牛云配置
 */
@Data
@Component
@ConfigurationProperties(prefix = "qiniu")
public class QiniuConfig {
    private String ak;
    private String sk;
    private String bucketDefault;
    private String domain;
}

接收自定义上传回复的实体

import io.swagger.annotations.ApiModel;
import lombok.*;

import java.io.Serializable;

/**
 * @Description:
 * @ClassName: QiniuPutResult
 */
@ApiModel(value = "七牛云存储返回结果", description = "七牛云存储返回结果")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class QiniuPutResult implements Serializable {
    private static final long serialVersionUID = xxxL;

    public String hash;
    public String key;
    public String fileUrl;
    public String bucket;
    public long fsize;
}

上传工具类

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.vdcloud.data.api.entity.QiniuPutResult;
import com.vdcloud.data.biz.config.QiniuConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 七牛云上传文件工具类
 * @ClassName: QiniuCloudUtil
 */
@Slf4j
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class QiniuCloudUtil {

    private final QiniuConfig qiniuConfig;

    /**
     * 获取上传的凭证
     *
     * @param key 上传key
     * @return 返回token
     */
    private String getUploadToken(String key) {
        Auth auth = Auth.create(qiniuConfig.getAk(), qiniuConfig.getSk());
        String uploadToken;
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody", "{\"fileUrl\":\"" + qiniuConfig.getDomain() + "$(key)\",\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}");
        putPolicy.put("insertOnly", 0);
        long expireSeconds = 3600;
        if (StrUtil.hasEmpty(key)) {
            uploadToken = auth.uploadToken(qiniuConfig.getBucketDefault(), null, expireSeconds, putPolicy);
            log.info("获取到的uploadToken:{}", uploadToken);
            return uploadToken;
        }
        uploadToken = auth.uploadToken(qiniuConfig.getBucketDefault(), key, expireSeconds, putPolicy);
        log.info("获取到的uploadToken:{}", uploadToken);
        return uploadToken;
    }

    /**
     * 上传文件到七牛云存储
     *
     * @param uploadBytes 文件的base64字符串
     * @param fileName    文件名称,key
     * @return
     */
    public QiniuPutResult uploadFileBytes(String uploadBytes, String fileName) {
        //定义一个正则表达式的筛选规则,为了获取图片的类型
        String rgex = "data:image/(.*?);base64";
        //获取图片类型
        String type = getSubUtilSimple(uploadBytes, rgex);
        log.info("图片类型=================>{}", type);
        //去除base64图片的前缀
        uploadBytes = uploadBytes.replaceFirst("data:(.+?);base64,", "");
        //把图片转换成二进制
        byte[] bytes = Base64.decodeBase64(uploadBytes.replaceAll(" ", "+"));

        //Configuration cfg = new Configuration(Zone.autoZone()) 已经过时了
        //北京属于华北地区,不同地区需要切换不同Region对象
        Configuration cfg = new Configuration(Region.region1());
        UploadManager uploadManager = new UploadManager(cfg);
        if (StrUtil.hasEmpty(fileName)) {
            fileName = IdUtil.simpleUUID();
        }
        String key = fileName + "." + type;
        try {
            Response response = uploadManager.put(bytes, key, getUploadToken(key));
            return response.jsonToObject(QiniuPutResult.class);
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过正则表达式取得文件的类型
     *
     * @param soap
     * @param rgex
     * @return
     */
    private String getSubUtilSimple(String soap, String rgex) {
        Pattern pattern = Pattern.compile(rgex);
        Matcher m = pattern.matcher(soap);
        while (m.find()) {
            return m.group(1);
        }
        return "";
    }
}

注意:

  • 使用@RequiredArgsConstructor(onConstructor = @__(@Autowired))注解,是为了防止QiniuConfig注入失败,有时候使用@Autowire或者@Resource会出现注入失败

  • 在接收到文件的base64字符串后,需要判断是否包含base64标识,如果包含,需要过滤掉,七牛云只需要base64内容,不需要标识

  • 通过网络接口接收到的base64需要使用Base64的decode方法将base64转为byte数组,不能直接使用String中的getBytes方法转为byte数组,否则文件无法正确解析

  • 七牛云存储是分区存储的,不同地区Region不一样

image.png

  • 目前常用的Base64算法用三种,第一种是sun公司提供的Base64算法,第二种是boundarycastle提供的加密算法,第三种是Apache的codec包,不推荐使用第一种,这些API可能在以后的jdk中被删除,如果使用了第一种算法,在使用Jenkins构建项目的时候会报错:com.sun.org.apache.xml.internal.security.utils does not exist。在项目中使用的是Apache的codec包

除特别注明外,本站所有文章均为东哥技术分享原创,转载请注明出处来自http://quliming.com/post/94.html

评论回复