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); try { BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations(); batchOperations.addDeleteOp(qi_niu_bucket, keys); Response response = bucketManager.batch(batchOperations); BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class); for (int i = 0; i < keys.length; i++) { BatchStatus status = batchStatusList[i]; String key = keys[i]; System.out.print(key + "\t"); if (status.code == 200) { System.out.println("delete success"); } else { System.out.println(status.data.error); } } return true; } catch (QiniuException ex) { System.err.println(ex.response.toString()); return false; } } }
然后我们从接口里面直接调用即可上传上去。
到此这篇关于Java实现上传网络图片到七牛云存储详解的文章就介绍到这了,更多相关Java上传图片到七牛云存储内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!