Springboot+七牛云实现图片上传和回显功能

记录下使用springboot实现的前端图片上传和访问工作

图片存放使用了七牛云的存储空间

1. 注册七牛云存储空间
注册

根据官方文档进行注册和存储空间的创建

spring boot 返回给前端map springboot给前端返回图片_spring boot

创建完的空间如上图,默认会分配一个一个月的测试用域名进行访问,这里仅学习使用已经足够了,有需要的可以绑定自己的域名

测试文件

上传了一部分测试的文件后续使用

spring boot 返回给前端map springboot给前端返回图片_七牛云存储_02

2.功能复现

前端先通过一个POST请求请求后端的common/upload接口进行图片上传,由后端返回上传成功后对应的图片名称

spring boot 返回给前端map springboot给前端返回图片_java_03

返回数据:

{
  "code": 1,
  "msg": null,
  "data": "45772076-bb22-44e9-92e4-4b9e64dfce5f.png",
  "map": {}
}

接收到返回数据后,前端再通过一个GET请求访问common/download获取对应资源

http://localhost:8080/common/download?name=45772076-bb22-44e9-92e4-4b9e64dfce5f.png
代码实现
QiniuUtils类

工具类,封装了七牛云官方SDK提供的接口,提供了两个方法uploaddownload

  • upload:接收传入的MultipartFile,进行上传,成功后返回对应的图片名(后续访问时会用到)
  • download:接收传入的图片名和客户端传来的HttpServletResponse,返回对应的图片文件链接
/*
* 处理七牛云文件上传/下载的工具类
* */
public class QiniuUtils {
    //配置
    private static String accessKey = "your accessKey";
    private static String secretKey = "your secretKey";
    private static String bucket = "your bucket";
    //根据七牛云储存空间位置设置对应Region
    private static Region region = Region.region2();
    //访问资源的外链域名
    private static String domain = "your domain";
    //是否启用https访问
    private static boolean useHttps = false;

    /*
     * 封装七牛云上传文件功能,上传成功返回对应的文件名称
     * */
    public static String upload(MultipartFile file){

        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(region);
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证upToken,然后准备上传
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        //原始名
        String usedName = file.getOriginalFilename();
        //根据原始名截取文件后缀
        String suffix = usedName.substring(usedName.lastIndexOf("."));
        //使用UUID生成32位随机名
        String key = UUID.randomUUID().toString() + suffix;
        String imgName = null;
        try {
            //进行文件上传
            Response response = uploadManager.put(file.getBytes(), key, upToken);
            //解析上传成功的结果,官方给出的示例用Gson解析了返回的response上传结果,本项目未引入Gson,修改为fastjson解析
            //DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
            imgName = putRet.key.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return imgName;
    }

    /*
     * 封装七牛云下载文件功能,返回一个可访问的url
     * */
    public static String download(String imgName) throws QiniuException {
        // imgName:下载资源在七牛云存储的名字
        DownloadUrl url = new DownloadUrl(domain, useHttps, imgName);
        //生成凭证
        Auth auth = Auth.create(accessKey, secretKey);
        //设置过期时间
        long l = System.currentTimeMillis();
        //1小时,可以自定义链接过期时间
        long expireInSeconds = 3600;
        long deadline = System.currentTimeMillis()+expireInSeconds;
        //生成url
        String urlString = url.buildURL(auth, deadline);
        return urlString;
    }
}
CommonController类

两个接口,分别响应前端的上传和回显功能
R是通用返回结果,服务端响应的数据最终都会封装成此对象

@RestController
@RequestMapping("common")
public class CommonController {

    @PostMapping("/upload")
    public R upload(MultipartFile file) {
        String imgName = QiniuUtils.upload(file);
        if (imgName != null){
            return R.ok(imgName);
        }
        return R.error();
    }

    @GetMapping("/download")
    public void download(String name, HttpServletResponse response) throws IOException {
        String pictureUrl = QiniuUtils.download(name);

        //建立图片连接
        URL url = new URL(pictureUrl);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        //设置请求方式
        connection.setRequestMethod("GET");
        //设置超时时间
        connection.setConnectTimeout(10*1000);
        //输入流
        InputStream stream = connection.getInputStream();
        //通过输出流,将文件写回到浏览器,在浏览器展示图片
        ServletOutputStream outputStream = response.getOutputStream();
        //设置响应回去的是什么类型的文件
        //TODO 这里可以通过七牛云官方SDK获取这个文件的类型
        //response.setContentType("image/jpg");
        //i/o读取
        int length = 0;
        byte[] bytes = new byte[1024];
        while (((length = stream.read(bytes)) != -1)) {
            outputStream.write(bytes, 0, length);
            outputStream.flush();
        }

        //关闭资源
        outputStream.close();
        stream.close();
    }
}