SpringBoot实现文件上传到七牛云

在做项目的过程中需要存储图片,所以选择将图片存储到七牛云上面,并将存储路径返回存储到数据库里。在网上看了很多篇文章,参考了一篇文章,结合自己的功能需求跑了一遍,记录下整个完成的过程。


目录

一、引入七牛云pom依赖:

二、application.yml:

三、在config里绑定配置文件:

四、在util里编写生成唯一图片名称的工具类:

五、编写上传文件接口UploadImageService:

六、 编写接口实现类UploadImageServiceImpl:

六、UploadController:

七、在postman测试一下:



一、引入七牛云pom依赖:

一开始我是直接在七牛云官方文档上直接复制下来的,但是在有些地方引用的时候说不能使用过时的类或方法,所以我就直接固定版本了。

<!--        七牛云依赖-->
<!--        <dependency>-->
<!--            <groupId>com.qiniu</groupId>-->
<!--            <artifactId>qiniu-java-sdk</artifactId>-->
<!--            <version>[7.7.0, 7.7.99]</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>7.2.18</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.14.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>happy-dns-java</artifactId>
            <version>0.1.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>


二、application.yml:

这些都可以在七牛云找到

oss:
  qiniu:
    url: http://七牛云的外链域名
    accessKey: 密钥AK
    secretKey: 密钥SK
    bucketName: 仓库名


三、在config里绑定配置文件:

package com.walnut.barter.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**七牛云配置类  绑定配置文件
 * @ClassName QiNiuYunConfig
 * @Description TODO
 * @Author Flechazo_lalala
 * Date 2021-11-17 17:02
 * @Version 1.0
 **/


@Data
@Configuration
public class QiNiuYunConfig {

    @Value("${oss.qiniu.url}")
    private String url;

    @Value("${oss.qiniu.accessKey}")
    private String AccessKey;

    @Value("${oss.qiniu.secretKey}")
    private String SecretKey;

    @Value("${oss.qiniu.bucketName}")
    private String BucketName;

}

四、在util里编写生成唯一图片名称的工具类:

package com.walnut.barter.common.util;

import java.util.UUID;

/**七牛云生成唯一图片名称的工具类
 * @ClassName StringUtil
 * @Description TODO
 * @Author Flechazo_lalala
 * Date 2021-11-17 17:07
 * @Version 1.0
 **/
public class StringUtil {
    public static String getRandomImgName(String fileName) {

        // 获取文件后缀
        int index = fileName.lastIndexOf(".");
        String suffix = fileName.substring(index);

        //检验文件
        if(".jpg".equals(suffix) || ".jpeg".equals(suffix) || ".png".equals(suffix)){
            //改变上传到服务器的文件名  uuid + suffix
            // 生成UUID
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String path = uuid + suffix;
            return path;
        }else{
            throw new IllegalArgumentException();
        }
    }
}

五、编写上传文件接口UploadImageService:

package com.walnut.barter.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * @ClassName UploadImageService
 * @Description TODO
 * @Author Flechazo_lalala
 * Date 2021-11-17 17:09
 * @Version 1.0
 **/
public interface UploadImageService {

    /**
     * 上传文件
     * @param file
     * @return
     */
    String uploadQNImg(MultipartFile file);


}

六、 编写接口实现类UploadImageServiceImpl:

我是华南地区的所以是zone2,如果是其他地区的需要修改。

华东:zone0    华北:zone1   华南:zone2   北美:na0   东南亚:as0

package com.walnut.barter.service.impl;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.walnut.barter.common.util.StringUtil;
import com.walnut.barter.config.QiNiuYunConfig;
import com.walnut.barter.service.UploadImageService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * @ClassName UploadImageServiceImpl
 * @Description TODO
 * @Author Flechazo_lalala
 * Date 2021-11-17 17:11
 * @Version 1.0
 **/


@Service
public class UploadImageServiceImpl implements UploadImageService {

    private QiNiuYunConfig qiNiuYunConfig;

    /**七牛文件上传管理器*/
    private UploadManager uploadManager;
    /**上传的token*/
    private String token;
    /**七牛认证管理*/
    private Auth auth;

    private BucketManager bucketManager;

    public UploadImageServiceImpl(QiNiuYunConfig qiNiuYunConfig) {
        this.qiNiuYunConfig = qiNiuYunConfig;
        init();
    }

    private void init() {
        // 我是华南地区的所以是zone2,如果是其他地区的需要修改
        uploadManager = new UploadManager(new Configuration(Zone.zone2()));
        auth = Auth.create(qiNiuYunConfig.getAccessKey(), qiNiuYunConfig.getSecretKey());
        // 根据命名空间生成的上传token
        bucketManager = new BucketManager(auth, new Configuration(Zone.zone2()));
        token = auth.uploadToken(qiNiuYunConfig.getBucketName());
    }


    /**
     * 上传文件
     * @param file
     * @return
     */
    @Override
    public String uploadQNImg(MultipartFile file) {
        String resultImage = "失败";
        try {
            // 判断图片后缀,并使用工具类根据上传文件生成唯一图片名称,防止截断字符如“%00”
            String fileName = file.getOriginalFilename();
            String imgName = StringUtil.getRandomImgName(fileName);

            //判断是否为恶意程序
            //通过流的方式把文件转换为BufferedImage对象,获取宽和高,只有图片才具有宽高属性
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if(bufferedImage == null || bufferedImage.getHeight()==0 || bufferedImage.getWidth()==0){
                return resultImage;
            }

            // 上传图片文件
            Response res = uploadManager.put(file.getInputStream(), imgName, token, null, null);
            if (!res.isOK()) {
                throw new RuntimeException("上传七牛出错:" + res.toString());
            }
            // 解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);

            // 直接返回外链地址
            return getPrivateFile(imgName);
        } catch (QiniuException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "失败";
    }

    /**
     * 获取私有空间文件
     *
     * @param fileKey
     * @return
     */
    @Override
    public String getPrivateFile(String fileKey) {
        String encodedFileName = null;
        String finalUrl = null;
        try {
            encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
            String publicUrl = String.format("%s/%s", this.qiNiuYunConfig.getUrl(), encodedFileName);
            //1小时,可以自定义链接过期时间
            long expireInSeconds = 3600;
            finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return finalUrl;
    }


    /**
     * 根据空间名、文件名删除文件
     * @param bucketName
     * @param fileKey
     * @return
     */
    @Override
    public boolean removeFile(String bucketName, String fileKey) {
        try {
            bucketManager.delete(bucketName, fileKey);
        } catch (QiniuException e) {
            e.printStackTrace();
        }
        return true;
    }

}

六、UploadController:

最后是控制层啦UploadController

这里的ResultInfo是封装好的统一接口类,大家可以自己修改,无伤大雅。

package com.walnut.barter.controller;


import com.walnut.barter.common.lang.ResultInfo;
import com.walnut.barter.common.util.ResultInfoUtil;
import com.walnut.barter.domain.vo.QiniuVo;
import com.walnut.barter.service.UploadImageService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;

/**
 * @ClassName UploadController
 * @Description TODO
 * @Author Flechazo_lalala
 * Date 2021-11-17 17:20
 * @Version 1.0
 **/
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class UploadController {

    @Autowired
    private UploadImageService uploadImageService;

    @ApiOperation("上传图片")
    @PostMapping("/image")
    public ResultInfo upLoadImage(@RequestParam("file") MultipartFile file){
        String result = "失败";
        QiniuVo qiniuVo = new QiniuVo();
        if(!file.isEmpty()){
            String path = uploadImageService.uploadQNImg(file);
            if(path.equals(result)){
                return ResultInfoUtil.buildError("上传失败");
            }else{
                System.out.println("七牛云返回的图片链接是:" + path);
                qiniuVo.setPath(path);
                return ResultInfoUtil.buildSuccess(qiniuVo);
            }
        }
        return ResultInfoUtil.buildError("上传失败");
    }

}

七、在postman测试一下:

1. 先是测试上传正确安全的图片

成功啦!再去七牛云确认一下,仓库里多了一个图片文件,并且文件链接和我返回的链接是一样的,复制文件链接也可以直接打开文件。

2. 再测试伪装成图片的病毒文件

对于文件的上传,一定要考虑文件的安全性!


好啦,这就是我的完成过程,如果有什么问题或者有什么想要补充的欢迎在评论里提出来,大家一起交流。

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
实现Spring Boot整合七牛云上传文件,可以按照以下步骤进行: 1.引入七牛云Java SDK 在pom.xml中引入七牛云Java SDK: ```xml <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>[7.2.0,)</version> </dependency> ``` 2.配置七牛云参数 在application.yml或application.properties中添加七牛云的参数: ```yml qiniu: accessKey: your_access_key secretKey: your_secret_key bucket: your_bucket_name domain: your_domain_name ``` 3.编写上传文件的代码 在需要上传文件的地方编写上传文件的代码,示例代码如下: ```java @Service public class QiniuService { @Autowired private QiniuConfig qiniuConfig; /** * 上传文件到七牛云 * * @param file 文件对象 * @return 文件访问URL */ public String uploadFile(File file) throws QiniuException { // 构造一个带指定Zone对象的配置类 Configuration cfg = new Configuration(Zone.autoZone()); // ...其他参数参考类注释 UploadManager uploadManager = new UploadManager(cfg); // 生成上传凭证,然后准备上传 String accessKey = qiniuConfig.getAccessKey(); String secretKey = qiniuConfig.getSecretKey(); String bucket = qiniuConfig.getBucket(); // 如果是Windows情况下,格式是 D:\\qiniu\\test.png String localFilePath = file.getAbsolutePath(); // 默认不指定key的情况下,以文件内容的hash值作为文件名 String key = null; Auth auth = Auth.create(accessKey, secretKey); String upToken = auth.uploadToken(bucket); try { Response response = uploadManager.put(localFilePath, key, upToken); // 解析上传成功的结果 DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); return qiniuConfig.getDomain() + "/" + putRet.key; } catch (QiniuException ex) { Response r = ex.response; System.err.println(r.toString()); try { System.err.println(r.bodyString()); } catch (QiniuException ex2) { // ignore } throw ex; } } } ``` 4.测试上传文件 在测试类中编写测试上传文件的代码,示例代码如下: ```java @RunWith(SpringRunner.class) @SpringBootTest public class QiniuServiceTest { @Autowired private QiniuService qiniuService; @Test public void testUploadFile() throws QiniuException { File file = new File("test.png"); String url = qiniuService.uploadFile(file); System.out.println(url); } } ``` 其中,test.png是要上传的文件名。运行测试类即可上传文件到七牛云,并返回文件的访问URL。 以上就是Spring Boot整合七牛云上传文件的全部步骤。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值