java实现上传网络图片到七牛云存储

Posted 穆雄雄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java实现上传网络图片到七牛云存储相关的知识,希望对你有一定的参考价值。

大家好,我是雄雄。

前言

最近阳了,第二条杠红的发紫,真难受啊,但是吧,博客上有个bug,不解决感觉比阳了还难受。

话还是要从博客的图片显示不出来这里说起,当时做的时候,在发文章这里,感觉没有封面的话,文章会很孤单,所以就设计了个封面这块儿。但是,封面如果太邋遢也还不如没有。

所以我就从网上的一个接口里面随机取的一些精美图片,本来好好的,结果今天一看,那个接口报错403了,当时就想着,这样做太依赖别人了,什么东西都得掌控在自己手里,不然出问题了难受的还是自己。

正好借这个机会,就重新设计了下,先从接口中取,如果接口中的图片能看,则用这个图片,顺便将这个图片传至七牛云存储中,否则就随机从七牛云存储中指定些图片展示出来,这样就不会受制于人。

效果图


直接将图片传至七牛云中,给我们返回该图片的地址。

代码实现

因为七牛云上传图片的时候,传递的是MultipartFile类型,所以我们需要将网络图片utl转换成流,然后在转换成MultipartFile,接着使用七牛云提供的方法上传即可。

下面我们先看看怎么将网络url转换成MultipartFile,这个代码网上很多,大家可以随便搜一个放上来就行,我这边封装了个工具类:FilesUtil

package com.shiyi.util;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.apache.http.entity.ContentType;
import org.apache.pdfbox.io.IOUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author: muxiongxiong
 * @date: 2022年12月29日 15:35
 * 博客:https://blog.csdn.net/qq_34137397
 * 个人站:https://www.穆雄雄.com
 * 个人站:https://www.muxiongxiong.cn
 * @Description: 类的描述
 */
public class FilesUtil 


    /**
     * 根据地址获得数据的输入流
     *
     * @param strUrl 网络连接地址
     * @return url的输入流
     */
    public static InputStream getInputStreamByUrl(String strUrl) 
        HttpURLConnection conn = null;
        try 
            URL url = new URL(strUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(20 * 1000);
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(conn.getInputStream(), output);
            return new ByteArrayInputStream(output.toByteArray());
         catch (Exception e) 
            e.printStackTrace();
         finally 
            try 
                if (conn != null) 
                    conn.disconnect();
                
             catch (Exception e) 
                e.printStackTrace();
            
        
        return null;
    

    /**
     * 将网络地址转换成MultipartFile
     * @param strUrl
     * @return
     */
    public static MultipartFile onlineAddressTransferFile(String strUrl)
        MultipartFile file = null;
        try 
            String fileName = strUrl.substring(strUrl.lastIndexOf("/") + 1);
            InputStream  stream = getInputStreamByUrl(strUrl);
            if (!ObjectUtils.isEmpty(stream)) 
                 file = new MockMultipartFile(fileName, fileName, "", stream);
                return file;
            
        catch (Exception exception)
            exception.printStackTrace();
        
        return file;
    



在调用的时候我们这样调:

  /**
     * 手动上传网络图片
     */
    @GetMapping(value = "/uploadFm")
    public ResponseResult uploadFm()
        MultipartFile multipartFile =  FilesUtil.onlineAddressTransferFile("https://img-community.csdnimg.cn/images/86f32eac875e42af9ed9e91b809dc7d8.png");
        return cloudOssService.upload(multipartFile);
    

剩下的就是七牛云里面的方法了,这边一起放上来吧:
CloudOssService接口代码:

package com.shiyi.service;

import com.shiyi.common.ResponseResult;
import org.springframework.web.multipart.MultipartFile;

public interface CloudOssService 
    /**
     * 上传
     * @param file 文件
     * @return
     */
    ResponseResult upload(MultipartFile file);

    /**
     * 批量删除文件
     * @param key 文件名
     * @return
     */
    ResponseResult delBatchFile(String ...key);


CloudOssServiceImpl实现类,主要是实现CloudOssService接口的:

package com.shiyi.service.impl;


import com.shiyi.common.ResponseResult;

import com.shiyi.enums.FileUploadModelEnum;
import com.shiyi.service.CloudOssService;
import com.shiyi.service.SystemConfigService;
import com.shiyi.strategy.context.FileUploadStrategyContext;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;

@Service
@RequiredArgsConstructor
public class CloudOssServiceImpl implements CloudOssService 

    private final SystemConfigService systemConfigService;

    private final FileUploadStrategyContext fileUploadStrategyContext;

    private String strategy;

    /**
     * 上传文件
     * @param file
     * @return
     */
    @Override
    public ResponseResult upload(MultipartFile file) 
        if (file.getSize() > 1024 * 1024 * 10) 
            return ResponseResult.error("文件大小不能大于10M");
        
        //获取文件后缀
        String suffix = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!"jpg,jpeg,gif,png".toUpperCase().contains(suffix.toUpperCase())) 
            return ResponseResult.error("请选择jpg,jpeg,gif,png格式的图片");
        
        getFileUploadWay();
        String key = fileUploadStrategyContext.executeFileUploadStrategy(strategy, file, suffix);
        return ResponseResult.success(key);
    


    /**
     * 删除文件
     * @param key
     * @return
     */
    @Override
    public ResponseResult delBatchFile(String ...key) 
        getFileUploadWay();
        Boolean isSuccess = fileUploadStrategyContext.executeDeleteFileStrategy(strategy, key);
        if (!isSuccess) 
            return ResponseResult.error("删除文件失败");
        
        return ResponseResult.success();
    

    private void getFileUploadWay() 
        strategy = FileUploadModelEnum.getStrategy(systemConfigService.getCustomizeOne().getFileUploadWay());
    


最后是文件上传策略上下文类:

package com.shiyi.strategy.context;

import com.shiyi.strategy.FileUploadStrategy;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;


/**
 * @apiNote 文件上传策略上下文
 */
@Service
@RequiredArgsConstructor
public class FileUploadStrategyContext 

    private final Map<String, FileUploadStrategy> fileUploadStrategyMap;

    /**
     * 执行文件上传策略
     *
     * @param file 文件对象
     * @return @link String 文件名
     */
    public String executeFileUploadStrategy(String fileUploadMode, MultipartFile file,String suffix) 
         return fileUploadStrategyMap.get(fileUploadMode).fileUpload(file,suffix);
    

    /**
     * 删除文件策略
     * @param fileUploadMode
     * @param key
     * @return
     */
    public Boolean executeDeleteFileStrategy(String fileUploadMode,String ...key) 
         return fileUploadStrategyMap.get(fileUploadMode).deleteFile(key);
    


QiNiuUploadStrategyImpl实现类的代码:

package com.shiyi.strategy.imp;

import com.alibaba.fastjson.JSON;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.BatchStatus;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.shiyi.entity.SystemConfig;
import com.shiyi.enums.QiNiuAreaEnum;
import com.shiyi.service.SystemConfigService;
import com.shiyi.strategy.FileUploadStrategy;
import com.shiyi.util.UUIDUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;


@Service("qiNiuUploadStrategyImpl")
@RequiredArgsConstructor
public class QiNiuUploadStrategyImpl implements FileUploadStrategy 

    private final Logger logger = LoggerFactory.getLogger(QiNiuUploadStrategyImpl.class);

    private final SystemConfigService systemConfigService;
    private String qi_niu_accessKey;
    private String qi_niu_secretKey;
    private String qi_niu_bucket;
    private Region region;
    private String qi_niu_url;

    @PostConstruct
    private void init()
        SystemConfig systemConfig = systemConfigService.getCustomizeOne();
        qi_niu_accessKey = systemConfig.getQiNiuAccessKey();
        qi_niu_secretKey = systemConfig.getQiNiuSecretKey();
        qi_niu_bucket = systemConfig.getQiNiuBucket();
        qi_niu_url = systemConfig.getQiNiuPictureBaseUrl();
        region = QiNiuAreaEnum.getRegion(systemConfig.getQiNiuArea());
    

    public void list() 
        Configuration configuration = new Configuration(region);
        Auth auth = Auth.create(qi_niu_accessKey, qi_niu_secretKey);
        BucketManager bucketManager = new BucketManager(auth,configuration);
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(qi_niu_bucket, null, 1000, null);
        while (fileListIterator.hasNext()) 
            FileInfo[] next = fileListIterator.next();
            for (FileInfo fileInfo : next) 
                logger.info("文件打印开始,文件名:",qi_niu_url + fileInfo.key);
                logger.info("文件类别打印开始,类别:",fileInfo.mimeType);
                logger.info("文件大小打印开始,大小:",fileInfo.fsize);
            
        
    

    /**
     * 七牛云文件上传
     * @param file 文件
     * @param suffix 后缀
     * @return
     */
    @Override
    public String fileUpload(MultipartFile file,String suffix) 
        String key = null;
        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(region);
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传
        Auth auth = Auth.create(qi_niu_accessKey, qi_niu_secretKey);
        String upToken = auth.uploadToken(qi_niu_bucket);
        InputStream inputStream = null;
        try 
            inputStream = file.getInputStream();
            //这里需要处理一下,不能让每次上去都是个UUID的文件名
            Response response = uploadManager.put(inputStream, "blog/"+UUIDUtils.getUuid() + "." + suffix, upToken,null,null);
            //解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(),DefaultPutRet.class);
            key =  qi_niu_url + putRet.key;
         catch (QiniuException ex) 
            Response r = ex.response;
            logger.error("QiniuException:",r.toString());
         catch (IOException e) 
            e.printStackTrace();
        finally 
            if (inputStream != null)
                try 
                    inputStream.close();
                 catch (IOException e) 
                    e.printStackTrace();
                
            
        
        return key;
    

    /**
     * 批量删除文件
     * @return
     */
    @Override
    public Boolean deleteFile(String ...keys) 
        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.region2());
        //...其他参数参考类注释
        Auth auth = Auth.create(qi_niu_accessKey, qi_niu_secretKey);
        BucketManager bucketManager = new BucketManager(auth, cfg);
        以上是关于java实现上传网络图片到七牛云存储的主要内容,如果未能解决你的问题,请参考以下文章

ueditor上传图片到七牛云存储(form api,java)

php表单上传图片到七牛云存储并返回地址……求具体流程~有代码更好

如何将图片上传到七牛云平台?

Vue 上传图片到七牛云实用攻略

前端上传图片头像到七牛云格式变成text

Go实战 | 电商平台 图片上传到七牛云