Loading

Springboot整合七牛云存储实现图片上传(详细)

本文参考:https://blog.csdn.net/weixin_41922289/article/details/90315999

创建Springboot工程

配置依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.duck.code</groupId>
    <artifactId>Springboot Qiniu</artifactId>
    <version>1.0-SNAPSHOT</version>

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

        <!-- springboot test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!--七牛-->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>7.2.7</version>
        </dependency>

        <!--工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!-- hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.3</version>
        </dependency>
    </dependencies>

</project>

配置yml配置文件

server:
  port: 8082

# 七牛云存储
oss:
  qiniu:
    domain: http://qdnolc9h2.bkt.clouddn.com # 访问域名(默认使用七牛云测试域名)
    accessKey: LbO-QxxxxxxxxoF4H3p # 公钥
    secretKey: TyJAtXx7xxxx_gxbA5k # 私钥
    bucketName: codeduck  #存储空间名称

创建配置类获取yml配置文件信息

package com.duck.code.config;


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


/**
 * CloudStorageConfig
 * @description 云存储配置类
 */
@Data
@Configuration
public class CloudStorageConfig {

    /**
     * 七牛域名domain
     */
    @Value("${oss.qiniu.domain}")
    private String qiniuDomain;
    /**
     * 七牛ACCESS_KEY
     */
    @Value("${oss.qiniu.accessKey}")
    private String qiniuAccessKey;
    /**
     * 七牛SECRET_KEY
     */
    @Value("${oss.qiniu.secretKey}")
    private String qiniuSecretKey;
    /**
     * 七牛空间名
     */
    @Value("${oss.qiniu.bucketName}")
    private String qiniuBucketName;

}

创建工具类StringUtil

StringUtil中创建方法getRandomImgName(String fileName) 根据上传文件名称,使用UUID生成唯一的图片名称,防止命名冲突

package com.duck.code.utils;

import cn.hutool.core.date.DateUtil;

import java.util.UUID;

/**
 * @program: codeduck
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 09:39
 **/
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 = "code/duck/" + DateUtil.today() + "-" + uuid + suffix;
        return path;
    }
}

创建抽象类UploadImageService

package com.duck.code.service;

import com.duck.code.config.CloudStorageConfig;

import java.io.FileInputStream;

/**
 * @program: Springboot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 19:48
 **/
public abstract class UploadImageService {

    protected CloudStorageConfig config;

    public abstract String uploadQNImg(FileInputStream file, String path);
}

实现抽象类UploadImageService

实现抽象类的具体功能

package com.duck.code.service.impl;

import com.duck.code.config.CloudStorageConfig;
import com.duck.code.service.UploadImageService;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
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 java.io.FileInputStream;


/**
 * @program: Springboot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 19:51
 **/
@Service
public class UploadImageServiceImpl extends UploadImageService {

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

    public UploadImageServiceImpl(CloudStorageConfig config){
        this.config = config;
        init();
    }

    private void init(){
        // 构造一个带指定Zone对象的配置类, 注意这里的Zone.zone0需要根据主机选择
        uploadManager = new UploadManager(new Configuration(Zone.zone0()));
        auth = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey());
        // 根据命名空间生成的上传token
        token = auth.uploadToken(config.getQiniuBucketName());
    }

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

            String path = config.getQiniuDomain() + "/" + putRet.key;
            // 这个returnPath是获得到的外链地址,通过这个地址可以直接打开图片
            return path;
        }catch (QiniuException e){
            e.printStackTrace();
        }
        return "";
    }
}

创建Web访问空间实现文件上传

package com.duck.code.controller;


import com.duck.code.service.UploadImageService;
import com.duck.code.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @program: SpringBoot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 16:12
 **/
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class UploadController {

    @Resource
    UploadImageService uploadImageService;

    @PostMapping(value = "/image")
    private String upLoadImage(@RequestParam("file") MultipartFile file) throws IOException {

        // 获取文件的名称
        String fileName = file.getOriginalFilename();

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

        if (!file.isEmpty()) {

            FileInputStream inputStream = (FileInputStream) file.getInputStream();

            String path = uploadImageService.uploadQNImg(inputStream, imgName);
            System.out.print("七牛云返回的图片链接:" + path);
            return path;
        }
        return "上传失败";
    }

}

创建静态访问Web页面index.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<script>
    /**
     * 上传图片
     */
    function uploadImg() {

        /**
         * formData在jquey中使用需要设置:
         * processData: false, // 告诉jQuery不要去处理发送的数据
         * contentType: false // 告诉jQuery不要去设置Content-Type请求头
         * @type {null}
         */
        var fd = new FormData();

        // 第一个参数为controller 接收的参数名称 , input的id
        fd.append("file", document.getElementById("inputId").files[0]);
        $.ajax({
            url: "http://localhost:8082/qiniu/image",
            type: "post",
            data: fd,
            processData: false,
            contentType: false,
            success: function (res) {
                console.log(res);

                if (res.status.code == 0) {
                    if (!$('#img').empty()) {
                        $('#img').empty();
                    }
                    // 这一串代码复制不上来 ,截图在下面
                    $('#img').append(" ![](+res.result[0]+)");
                } else {
                    alert("图片上传失败");
                }
            },
            dataType: "json"
        })
    }
</script>
    <div id="img" style="margin: 200px">
        <input type="file" name="text" id="inputId">
        <br/><br/>
        <input type="submit" onclick="uploadImg()">
    </div>
</body>
</html>

测试

web访问:

image-20200730210305475

后台打印上传路径

image-20200730210706431

posted @ 2020-07-30 21:09  codeduck  阅读(6154)  评论(5编辑  收藏  举报