SpringBoot集成七牛云-实现文件上传、下载、解决报错、详细案例

用自己电脑做文件存储,我想没谁愿意了吧,来来和我一起白嫖吧,伙伴们!!!😁
七牛云:也是一个对象存储的云网站,当时用它是因为可以每次白嫖10个G的使用一个月,用完可以新开空间,接着用。如果有自己的域名的话,可以一直用。也可以省自己电脑内存捂脸(😂)

很喜欢一句话:”八小时内谋生活,八小时外谋发展“

我们:"待别日相见时,都已有所成”

在这里插入图片描述
放张图片先舒缓下心情啦

一、背景

确实是每月10G,亲测有效。😁 (我不是推广人员,只是感觉平时写什么小Demo,写个作业啥的,用起来挺爽的。)
在这里插入图片描述

在网上找了一圈,都没有看到一个能够跑动的案例,要么太久远,要么就实现不了。最后实在没法去找了学长,他给我发了一份文档,才算学会。

我当时的功能需求:希望上传一张图片,然后能够返回这个图片的外链链接。

一直卡在返回图片外链链接上,一直报一个错误,就是不能够回显到页面上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tm3c7ata-1619319691612)(springboot_七牛云.assets/image-20210425092840777.png)]

获取外链需要写下面这段代码。

最后才有这篇博客的出现,希望大家能够及时避坑。

二、具体步骤

2.1、工程目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YUCGkKFU-1619319691614)(springboot_七牛云.assets/image-20210425104905970.png)]

2.2、导入依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--七牛云-->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>[7.2.0, 7.2.99]</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies> <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--七牛云-->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>[7.2.0, 7.2.99]</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

2.3、yaml配置文件

server:
  port: 8082
oss:
  qiniu:
    url: http://qs22nqygb.hn-bkt.clouddn.com # 这里如果有自己的域名就去绑定自己的 没有的就只能使用七牛云的测试域名
    accessKey: 公共密钥 #
    secretKey: 私钥 # 
    bucketName: wyhdsg  #空间名

2.4、绑定配置文件

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

@Data
@Configuration
public class QiNiuYunConfig {
    /**
     * 七牛域名domain
     */
    @Value("${oss.qiniu.url}")
    private String url;
    /**
     * 七牛ACCESS_KEY
     */
    @Value("${oss.qiniu.accessKey}")
    private String AccessKey;
    /**
     * 七牛SECRET_KEY
     */
    @Value("${oss.qiniu.secretKey}")
    private String SecretKey;
    /**
     * 七牛空间名
     */
    @Value("${oss.qiniu.bucketName}")
    private String BucketName;

}

2.5、生成唯一图片名称的工具类


public class StringUtil {

    /**
     * @Description: 生成唯一图片名称
     * @Param: fileName
     * @return: 云服务器fileName
     */
    public static String getRandomImgName(String fileName) {
        int index = fileName.lastIndexOf(".");
        if ((fileName == null || fileName.isEmpty()) || index == -1){
            throw new IllegalArgumentException();
        }
        // 获取文件后缀
        String suffix = fileName.substring(index);
        // 生成UUID
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 生成上传至云服务器的路径
//        String path = "news/crush/"+ DateUtil.today() + "-" + uuid + suffix;
        String path = uuid + suffix;
        return path;
    }
}

2.6、UploadImageService

import org.springframework.web.multipart.MultipartFile;


public interface UploadImageService {

    String uploadQNImg(MultipartFile file);

    String getPrivateFile(String fileKey);

    boolean removeFile(String bucketName, String fileKey);

}

2.7、UploadImageServiceImpl

import com.crush.config.QiNiuYunConfig;
import com.crush.service.UploadImageService;
import com.crush.utils.StringUtil;
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 org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;



@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() {
        // 构造一个带指定Zone对象的配置类, 注意这里的Zone.zone0需要根据主机选择
        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, key]
     * @return java.lang.String
     **/
    @Override
    public String uploadQNImg(MultipartFile file) {
        try {
            // 获取文件的名称
            String fileName = file.getOriginalFilename();

            // 使用工具类根据上传文件生成唯一图片名称
            String imgName = StringUtil.getRandomImgName(fileName);

            FileInputStream inputStream = (FileInputStream) file.getInputStream();
            // 上传图片文件
            Response res = uploadManager.put(inputStream, 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);
            long expireInSeconds = 3600;//1小时,可以自定义链接过期时间
            finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return finalUrl;
    }

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

}

2.8、UploadController

import com.crush.service.UploadImageService;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
@Controller
public class UploadController {

    @Resource
    UploadImageService uploadImageService;

    @GetMapping("/upload")
    public String upload(){
        return "upload";
    }


    @PostMapping(value = "/image")
    private String upLoadImage(@RequestParam("file") MultipartFile file, Model model) {

        if (!file.isEmpty()) {
            String path = uploadImageService.uploadQNImg(file);
            System.out.print("七牛云返回的图片链接:" + path);
            model.addAttribute("link",path);
            return "upload";
        }
        return "";
    }

    /*
     * 这里为了方便测试才这么写的 可以根据实际需要 自己写。
     * @Param
     * @return java.lang.String
     **/
    @ResponseBody
    @DeleteMapping("/remove")
    public String removeFile(){
        uploadImageService.removeFile("wyhdsg","0b677574afdf4a8ea1271108f1176bde.jpg");
        return "删除成功";
    }

}

2.9、测试页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>
<form action="/image" method="post" enctype="multipart/form-data">
    <label>上传图片</label>
    <input type="file" name="file"/>
    <input type="submit" value="上传"/>
    <p>回显图片:</p>
    <img th:src="${link}"/>
</form>
</body>
</html>

2.10、测试图片

这里也可以用postman测试的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n5zlpROF-1619319691619)(springboot_七牛云.assets/image-20210425105547353.png)]

三、自言自语

🙅‍可爱的我。

希望这篇博客能够帮助到你。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EGN6fjhS-1619319691622)(springboot_七牛云.assets/21f15fe11b7a84d2f2121c16dec50a4e4556f865.png@100w_100h.webp)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mw2TifMQ-1619319691623)(springboot_七牛云.assets/9c78c14bd395d75afeecd20276ec71324e9b97df.png@100w_100h.webp)]

Spring Boot整合七牛云是一个常见的用于文件存储和管理的任务。七牛云提供了一套完整的RESTful API和SDK,可以方便地在Spring应用中集成。以下是实现这些功能的基本步骤: 1. **添加依赖**: - 首先,在你的`pom.xml`中引入七牛官方的Java SDK依赖,如Spring Cloud Storage和Qiniu SDK。 ```xml <dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>7.4.0+</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> ``` 2. **配置七牛账号信息**: 在`application.properties`或`application.yml`中添加七牛的Access Key、Secret Key以及Bucket名称等配置。 ```properties qiniu.accessKey=<your_access_key> qiniu.secretKey=<your_secret_key> qiniu.bucketName=<your_bucket_name> ``` 3. **创建上传服务**: 使用`QiniuUploader`类,你可以创建一个上传策略(包括是否生成缩略图、过期时间等)。然后调用`put`方法上传文件。 ```java @Autowired private QiniuManager qiniuManager; public String uploadFile(MultipartFile file) { // 检查文件有效性 if (file.isEmpty()) return "File is empty"; // 创建上传策略 Uploader uploader = new Uploader(qiniuManager.getUpToken(), file.getOriginalFilename()); try { String key = uploader.put(file.getInputStream(), null); // key是你在七牛上保存的文件名 return "Upload successful, key: " + key; } catch (Exception e) { return "Error uploading file: " + e.getMessage(); } } ``` 4. **下载和删除文件**: 对于下载,使用`get`方法,传入文件的Key即可。删除则通过`delete`方法,同样需要token。 ```java public ResponseResult downloadFile(String key) { ResponseInfo info = qiniuManager.getFile(key); // 下载并返回文件内容 } public boolean deleteFile(String key) { return qiniuManager.deleteFile(key) > 0; // 返回布尔值表示删除成功与否 } ``` 5. **处理错误和异常**: 七牛API可能会抛出各种异常,记得捕获并妥善处理。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值