springboot整合七牛云——前端获取凭证token,用户客户端直传七牛服务、服务端上传

前言

该功能系在公司开发的过程中写出,做个记录,包括七牛云的文件服务器直传、删除、确认文件存在以及客户端的携带凭证上传,更多关于七牛的详细说明,魔法变量参数值意义,见下方七牛官方文档。

1.七牛官方Java文档

https://developer.qiniu.com/kodo/1239/java

2.后端接口

2.1. springboot添加依赖

<dependency>
  <groupId>com.qiniu</groupId>
  <artifactId>qiniu-java-sdk</artifactId>
  <version>[7.7.0, 7.7.99]</version>
</dependency>

2.2. 获取密钥

https://portal.qiniu.com/user/key

2.3. 添加yml配置信息

qiniu:
  accessKey: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
  secretKey: sssssssssssssssssssssssssssssssssssssssss
  bucket: bbbbbbbbb  # 创建的存储空间名 https://portal.qiniu.com/kodo/bucket
  path: https://img.?????.com/ # 对应存储空间的访问域名
  expireSeconds: 1800 #policy过期时间 秒

2.4. 创建配置文件

import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Data
@Component
@Configuration
@ConfigurationProperties(prefix = "qiniu")
public class QiniuConfig {

    private String accessKey;

    private String secretKey;

    private String bucket;

    private String path;

    private Long expireSeconds;

    /**
     * 华东机房
     */
    @Bean
    public com.qiniu.storage.Configuration qnConfig() {
        return new com.qiniu.storage.Configuration(Region.region0());
    }

    /**
     * 构建一个七牛上传工具实例
     */
    @Bean
    public UploadManager uploadManager() {
        return new UploadManager(qnConfig());
    }

    /**
     * 认证信息实例
     *
     * @return
     */
    @Bean
    public Auth auth() {
        return Auth.create(accessKey, secretKey);
    }

    /**
     * 构建七牛空间管理实例
     */
    @Bean
    public BucketManager bucketManager() {
        return new BucketManager(auth(), qnConfig());
    }
}

2.5. service层

import com.alibaba.fastjson.JSONObject;
import com.qiniu.common.QiniuException;
import com.qiniu.storage.model.FetchRet;
import com.qiniu.storage.model.FileInfo;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Map;

public interface FileService {

    //删除七牛云文件
    Boolean deleteFile(String key);

    //检查文件是否存在于七牛云
    FileInfo checkFile(String key);

    //服务本地上传图片,需要指定path路径
    Map<String,String> uploadImg(MultipartFile files,String path);

    //抓取网络资源到空间
    FetchRet fetchNetSource(NetAddress target);

    //七牛云本地上传方法本体
    Map uploadFile(File file,String filePath,String fileName) throws QiniuException;

    //前端上传凭证
    JSONObject getQiniuPolicy();
}

2.6. service实现

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FetchRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import com.wenhu.app.config.QiniuConfig;
import com.wenhu.app.enums.ExceptionEnum;
import com.wenhu.app.exception.WenHuException;
import com.wenhu.app.service.FileService;
import com.wenhu.app.util.MultipartFileToFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class ImpFileService implements FileService {

    @Autowired
    private UploadManager uploadManager;

    @Autowired
    private BucketManager bucketManager;

    @Autowired
    private Auth auth;

    @Autowired
    private QiniuConfig qiniuConfig;

    private String getUploadToken() {
        return this.auth.uploadToken(qiniuConfig.getBucket(), null, 3600, null);
    }

	//删除
    @Override
    public Boolean deleteFile(String key) {
        if(checkFile(key)==null){
            return true;
        }else{
            try {
                bucketManager.delete(qiniuConfig.getBucket(), key);
                return true;
            } catch (QiniuException e) {
                log.error(e.getMessage());
                throw new WenHuException(ExceptionEnum.QiNiu_Error);
            }
        }
    }

    //检查文件是否存在于七牛云
    @Override
    public FileInfo checkFile(String key) {
        FileInfo fileInfo = null;
        try {
            fileInfo = bucketManager.stat(qiniuConfig.getBucket(), key);
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        return fileInfo;
    }

    /**
     * 单图单文件上传
     * @param files
     * @return
     */
    @Override
    public Map<String,String> uploadImg(MultipartFile files,String path) {
        String fileName = files.getOriginalFilename();
        File file = new File(path+fileName);
        String imgName = "";
        try {
            //将MulitpartFile文件转化为file文件格式
            files.transferTo(file);
            //得到上传返回的结果
            Map response = uploadFile(file,path,fileName);
            //七牛云上图片名称hash值
            //String imgHash = (String) response.get("imgHash");
            //七牛云上图片Name
            imgName = (String) response.get("imgName");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //删除本地临时文件副本
        //MultipartFileToFile.delteTempFile(file);
        Map map =new HashMap();
        map.put("image",imgName);
        return map;
    }

    @Override
    public FetchRet fetchNetSource(NetAddress target) {
        FetchRet fetchRet = null;
        try {
            fetchRet = bucketManager.fetch(target.getUrl(), qiniuConfig.getBucket(), LocalDate.now()+"/"+ IdUtils.fastSimpleUUID());
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        if(fetchRet == null){
            throw new ServiceException("资源抓取失败", HttpStatus.NOT_FOUND);
        }
        /**
         * TODO target.getFormat() 和 fetchRet.mineType 校验所抓取的文件是否符合预期
         * 不符合 执行七牛删除文件并返回提示
         */
        fetchRet.key=qiniuConfig.getPath()+fetchRet.key;
        return fetchRet;
    }

    /* 向七牛上传文件方法的本体 */
    @Override
    public Map uploadFile(File file,String filePath,String fileName) throws QiniuException {
        Map map = new HashMap();
        LocalDateTime dateTime=LocalDateTime.now();
        Response response =
                this.uploadManager.put
                        (file,
                                filePath+dateTime.getYear()+""+dateTime.getMonthValue()+""+dateTime.getDayOfMonth()+""+dateTime.getHour()+""+dateTime.getMinute()+""+dateTime.getSecond()
                                        +"/"+fileName, getUploadToken());
        //解析上传的结果
        DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
        String imgName = putRet.key;
        String imgHash = putRet.hash;
        int retry = 0;
        while (response.needRetry() && retry < 3) {
            response = this.uploadManager.put(file, null, getUploadToken());
        }
        map.put("imgName", imgName);
        map.put("response", response);
        map.put("imgHash", imgHash);
        //删除本地临时文件副本
        MultipartFileToFile.delteTempFile(file);
        return map;
    }

    @Override
    public JSONObject getQiniuPolicy() {
        JSONObject json = new JSONObject();
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody",
                "{\"key\":\"$(key)\"," +
                        "\"hash\":\"$(etag)\"," +
                        "\"bucket\":\"$(bucket)\"," +
                        "\"fsize\":\"$(fsize)\"," +
                        "\"mimeType\":\"$(mimeType)\"}");
        putPolicy.put("mimeLimit","!application/json;text/plain");
        json.put("token", auth.uploadToken(qiniuConfig.getBucket(), null, qiniuConfig.getExpireSeconds(), putPolicy));
        json.put("url", qiniuConfig.getPath());
        json.put("dirPrefix", LocalDate.now() + "/");
        return json;
    }
}

2.7.

import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class MultipartFileToFile {

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     *
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }
}

2.8. controller方法

@RestController
@RequestMapping("thirdPart")
@Api(tags = "第三方服务接口")
public class ThirdPartController {

    @Autowired
    FileService fileService;

    @GetMapping("/qiniu/policy")
    @ApiOperation("获取客户端上传七牛凭证")
    public BaseResponse qiniuPolicy() {
        JSONObject json = fileService.getQiniuPolicy();
        return BaseResponse.ok(json);
    }

    @PostMapping("/qiniu/fetchNetSource")
    @ApiOperation("图片或文件网络地址抓取到七牛,并返回存储七牛后文件信息")
    public BaseResponse fetchNetSource(@RequestBody NetAddress target) {
        return BaseResponse.ok(fileService.fetchNetSource(target.getUrl()));
    }
}
import lombok.Data;

@Data
public class NetAddress {

    //待抓取的 文件url
    private String url;

    //过滤文件格式
    private String format;
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Tenk_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值