使用springboot将本地图片上传到七牛云

在项目需求中需要用到图片上传的功能,决定将图片上传到图床使用,这里选用七牛云服务器。
在springboot的项目中,将结合代码上传本地图片至七牛云。

一. 准备七牛云账号

1. 申请七牛云账号

如果您还没有七牛云账号,可以先去七牛云官网注册账号,注册成功后登录进入管理控制台。
在这里插入图片描述

2.按需创建存储空间

七牛云新建存储空间参考文档 不懂的可以查看官方文档

  1. 在管理控制台界面点击左侧【对象存储】
    在这里插入图片描述
  2. 点击【新建存储空间】(因为我已经有一个空间,这里只是演示一下)
    在这里插入图片描述
    新建存储空间完成后,七牛云会给我们一个测试用的域名,但是这个域名只有30天的有效时间,30天后会自动失效。
    在这里插入图片描述
    注意:如果没有自己的域名,以下的第3步和第4步可以直接跳过哦

3. 从测试域名过渡到自定义域名

详情请查看官方文档,就不做过多解释了从测试域名过渡到自定义域名

4. 配置域名的 CNAME

详情请查看官方文档如何配置域名的CNAME
以上准备工作做完后,开始代码编写的过程。

二. springboot整合七牛云

此项目使用 springboot 搭建

  1. 将七牛云的相关依赖项添加到pom.xml 文件中
<!--七牛云-->
<dependency>
    <groupId>com.qiniu</groupId>
    <artifactId>qiniu-java-sdk</artifactId>
    <version>[7.2.0, 7.2.99]</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.3.1</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.6.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.qiniu</groupId>
    <artifactId>happy-dns-java</artifactId>
    <version>0.1.4</version>
    <scope>compile</scope>
</dependency>
  1. application.properties 文件中编写七牛云的配置
    在这里插入图片描述
# 七牛云相关配置
# bucket 是创建的存储空间名
# path 对应存储空间的访问域名
qiniu.accessKey=
qiniu.secretKey=
qiniu.bucket=
qiniu.path=
baseUploadUrl= c://xianer/images/

相关参数含义
进入七牛云管理控制台的【密钥管理】查看 accessKeysecretKey
在这里插入图片描述
bucket 是我们之前创建的存储空间名称
在这里插入图片描述
path 是我们的测试域名或自定义域名
baseUploadUrl 是自定义的本地文件路径,七牛云在图片上传过程中会在本地临时存储文件,可以自己修改文件路径。
3. 在 config 包下新建一个 FileUploadConfig 的配置类

package cn.duli.xianer.config;


import com.google.gson.Gson;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
import java.io.File;

@Configuration
@ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class})
@ConditionalOnProperty(prefix = "spring.http.multipart", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(MultipartProperties.class)
public class FileUploadConfig {


    private final MultipartProperties multipartProperties;

    @Value("${baseUploadUrl}")
    private String baseUploadUrl;

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

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

    public FileUploadConfig(MultipartProperties multipartProperties) {
        this.multipartProperties = multipartProperties;
    }

    /**
     * 上传配置
     */
    @Bean
    @ConditionalOnMissingBean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        judge(baseUploadUrl);
        factory.setLocation(baseUploadUrl);
        return factory.createMultipartConfig();
    }

    public void judge(String filePath){
        File file = new File(filePath);
        if(!file.exists()){
            file.mkdir();
        }
    }

    /**
     * 注册解析器
     */
    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
    @ConditionalOnMissingBean(MultipartResolver.class)
    public StandardServletMultipartResolver multipartResolver() {
        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
        return multipartResolver;
    }

    /**
     * 华南机房(特别注意)
     */
    @Bean
    public com.qiniu.storage.Configuration qiniuConfig() {
        return new com.qiniu.storage.Configuration(Zone.zone2());
    }

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


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

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

    /**
     * 配置gson为json解析工具
     *
     * @return
     */
    @Bean
    public Gson gson() {
        return new Gson();
    }
}

**注意:**在第3步中,需要查看你自己新建的存储空间所属区域,区域必须 与 构建配置类中的 Zone.zone2() 一 一对应

 /**
     * 华南机房(特别注意)
     */
    @Bean
    public com.qiniu.storage.Configuration qiniuConfig() {
        return new com.qiniu.storage.Configuration(Zone.zone2());
    }

其他常见的所属配置

 Configuration cfg = new Configuration(Zone.zone0());//Zone.zone0() 指华东
 Configuration cfg = new Configuration(Zone.zone1());//华北
 Configuration cfg = new Configuration(Zone.zone2());//华南
  1. service 包下新建一个 FileService 的接口
package cn.duli.xianer.service;

import com.qiniu.common.QiniuException;

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

public interface FileService {

    /**
     * 多文件上传
     * @param file
     * @return
     * @throws QiniuException
     */
    Map uploadFile(File file) throws QiniuException;
}
  1. impl 包下新建 FileServiceImpl 实现类
package cn.duli.xianer.service.impl;

import cn.duli.xianer.service.FileService;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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


@Service
public class FileServiceImpl implements FileService {


    @Autowired
    private UploadManager uploadManager;

    @Autowired
    private Auth auth;


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


    private StringMap putPolicy;

    @Override
    public Map uploadFile(File file) throws QiniuException {
        Map map = new HashMap();
        Response response = this.uploadManager.put(file,null,getUploadToken());
        //解析上传的结果
        DefaultPutRet putRet = new Gson().fromJson(response.bodyString(),DefaultPutRet.class);

        String imageName = putRet.hash;
        int retry = 0;
        while(response.needRetry() && retry < 3){
            response = this.uploadManager.put(file,null,getUploadToken());
        }
        map.put("response",response);
        map.put("imgName",imageName);
        return map;
    }



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

}
  1. controller 包下新建一个 TestController 类,用来测试图片上传
package cn.duli.xianer.controller;

import cn.duli.xianer.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/upload")
public class TestController {

    @Autowired
    FileService fileService;

    @Value("${baseUploadUrl}")
    private String url;

    /**
     * 多图上传
     * @param upfiles
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/uploadImg")
    public List<Map<String,Object>> uploadImg(@RequestParam(value = "files")MultipartFile upfiles[]) throws IOException {
        List<Map<String,Object>> listMaps = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        System.out.println(upfiles);
        try{
            if(upfiles!=null) {
                for (int i=0;i<upfiles.length;i++) {
                    if (!upfiles[i].isEmpty()) {
                        String fileName = upfiles[i].getOriginalFilename();
                        File file = new File(url + fileName);
                       // 将MulitpartFile文件转化为file文件格式
                        upfiles[i].transferTo(file);
                        Map response = fileService.uploadFile(file);
                        Object imageName = response.get("imgName");
                        map.put("url",imageName);
                        listMaps.add(map);
                        System.out.println(upfiles[i]);
                    }
                }
                System.out.println(listMaps);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return listMaps;
    }


}

以上都完成了过后,我们使用 postman 测试多图上传接口

注意:使用 postman 测试图片上传时,Headers头部不能有任何东西,如果有 Content-Type 的话,需要取消勾选,否则图片会上传失败
在这里插入图片描述
Body:
选择Body
选择form-data
key:后台规定的接收文件的名称参数(切记不是你传的图片名称)
key的格式选择为File
value:自动变成 选择文件
点击 send 即可将图片上传成功
在这里插入图片描述
查看七牛云中是否上传成功,在管理控制台的空间管理-》文件管理中查看
在这里插入图片描述
最后,使用 域名+文件名 就可以访问图片啦~

补充:如果只需要实现单张图片上传到七牛云服务器,则只修改 TestController 中的代码即可

package cn.duli.xianer.controller;

import cn.duli.xianer.service.FileService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/upload")
public class TestController {

    @Autowired
    FileService fileService;

    @Value("${baseUploadUrl}")
    private String url;

    /**
     * 单图上传
     * @param upfiles
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/uploadImg")
    public Map<String,Object> uploadImg(@RequestParam(value = "file")MultipartFile upfile) throws IOException {
        Map<String,Object> map = new HashMap<>();
        String fileName = upfile.getOriginalFilename();
        File file = new File(url + fileName);
        try{
			//将MulitpartFile文件转化为file文件格式
            upfile.transferTo(file);
            Map response = fileService.uploadFile(file);
            Object imageName = response.get("imgName");
            map.put("url",imageName);
        }catch (Exception e){
            e.printStackTrace();
        }
        return map;
    }
}

发布了15 篇原创文章 · 获赞 10 · 访问量 2707

猜你喜欢

转载自blog.csdn.net/qq_38157825/article/details/104631676