目录
一、前言
最近在做有关文件上传得项目,一般来说服务器足够大,将图片上传到本地服务器倒也够用,但是如果我们得服务器过小,或者随着运营时间推进,图片资源将占用服务器大量得空间,这时候,我们可以考虑使用OSS
对象存储。
OSS(Object Storage Service)
对象关系存储。
OSS
是在云上提供无层次结构的分布式存储产品,为用户提供单价较低且快速可靠的数据存储方案。
简单点:用户把静态数据如图片、视频、js、html、css等等放入到Bucket
中,然后每个数据对象会得到一个唯一的访问地址,客户端只需要通过REST API去获取资源就行了。
例子:酒店服务生帮我泊车,然后会给我张凭证,我不关心他帮我停在停车场的几楼哪个车位,我离开时只需要将凭证给他,他就会帮我把车取出来。在这里“停车场”可以看作是一个Bucket
,我的“车”可以看作是一个数据对象,“凭证”可以看作一个唯一的URL
,通过HTTP
方式访问这个URL
就可以得到我的车(数据对象)。
下面我们以七牛云平台为例子,实现SpringBoot
整合七牛云,实现文件的上传返回文件链接。
二、准备工作
我们需要注册七牛云账户
注册登录后新建空间
创建空间后,会有一个默认的链接
我们可以自定义域名,也可以使用官网提供的域名,这里我们以默认的域名为例子
详细创建空间参考:
创建空间教程
三、代码编写
3.1、引入Maven依赖
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.7.0, 7.7.99]</version>
</dependency>
3.2、配置yaml文件
qiniu:
accessKey: xxx # 公钥
secretKey: xxx # 私钥
bucketName: race-medical
path: http://xxxx.com
公钥与私钥可以到密钥管理处查看
bucket
为创建的对象存储的空间名称
path
为文件管理中的外链域名(默认使用七牛云测试域名)
3.3、配置类
package com.csust.medicalassistant.config;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class UploadConfig {
@Value("${qiniu.accessKey}")
private String accessKey;
@Value("${qiniu.secretKey}")
private String secretKey;
@Bean
public Auth getAuth(){
return Auth.create(accessKey,secretKey);
}
@Bean
public UploadManager getUploadManager(){
return new UploadManager(new Configuration());
}
}
其中Auth.create()
传入公钥私钥以创建权限,供UploadManager
上传文件时使用
3.4、七牛云工具类
package com.csust.medicalassistant.utils;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.FileInputStream;
@Component
public class QiniuUtils {
@Autowired
private UploadManager uploadManager;
@Autowired
private Auth auth;
@Value("${qiniu.bucketName}")
private String bucketName;
@Value("${qiniu.path}")
private String url;
public String upload(FileInputStream file, String fileName) throws QiniuException {
String token = auth.uploadToken(bucketName);
fileName = "myimage/"+fileName;
Response res = uploadManager.put(file, fileName, token, null, null);
if (!res.isOK()) {
throw new RuntimeException("上传七牛云出错:" + res);
}
return url+"/"+fileName;
}
}
注意:
myimage
是我在空间中创建的文件名称,当加上文件名称,图片上传至七牛云时,会自动上传至该文件中
3.5、图片处理工具类
package com.csust.medicalassistant.utils;
import com.csust.medicalassistant.common.CommonResult;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
/**
* @author niuben
*/
@Component
public class ImageUtil {
// 生成图片名称
public String resetFileName(MultipartFile file){
String originalFileName = file.getOriginalFilename();
String ext = "." + originalFileName.split("\\.")[1];
String uuid = UUID.randomUUID().toString().replace("-","");
return uuid + ext;
}
/**
* @Description: 生成唯一图片名称
* @Param: fileName
* @return: 云服务器fileName
*/
public String getRandomImgName(String fileName) {
int index = fileName.lastIndexOf(".");
if (fileName.isEmpty() || index == -1){
throw new IllegalArgumentException();
}
// 获取文件后缀
String suffix = fileName.substring(index).toLowerCase();
// 生成UUID
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
// 生成上传至云服务器的路径
return "userAvatar:" + uuid + suffix;
}
/**
* 图片转为byte数组
* @param path
* @return
* @throws IOException
*/
public byte[] image2byte(String path) throws IOException {
byte[] data = null;
URL url = null;
InputStream input = null;
try{
url = new URL(path);
HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
httpUrl.getInputStream();
input = httpUrl.getInputStream();
}catch (Exception e) {
e.printStackTrace();
return null;
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int numBytesRead = 0;
while ((numBytesRead = input.read(buf)) != -1) {
output.write(buf, 0, numBytesRead);
}
data = output.toByteArray();
output.close();
input.close();
return data;
}
}
3.6、Service层
package com.csust.medicalassistant.service.impl;
import com.csust.medicalassistant.common.CommonResult;
import com.csust.medicalassistant.common.ResultCode;
import com.csust.medicalassistant.service.QiniuService;
import com.csust.medicalassistant.utils.ImageUtil;
import com.csust.medicalassistant.utils.QiniuUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Objects;
/**
* @author niuben
*/
@Slf4j
@Service
public class QiniuServiceImpl implements QiniuService {
@Autowired
private QiniuUtils qiniuUtils;
@Resource
private ImageUtil imageUtil;
@Override
public CommonResult<String> upload(MultipartFile file) {
if (file.isEmpty()) {
return CommonResult.failed("文件为空!");
}
String fileName = imageUtil.resetFileName(file);
try {
FileInputStream uploadFile = (FileInputStream) file.getInputStream();
String path = qiniuUtils.upload(uploadFile, fileName);
return CommonResult.success(path);
} catch (IOException e) {
e.printStackTrace();
return CommonResult.failed(ResultCode.FAILED);
}
}
}
3.7、controller层
package com.csust.medicalassistant.controller;
import com.csust.medicalassistant.common.CommonResult;
import com.csust.medicalassistant.service.QiniuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* @author niuben
*/
@Api(tags = "七牛云接口")
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class QiniuController {
@Autowired
private QiniuService qiniuService;
@ApiOperation("上传图片")
@PostMapping(value = "/upload")
public CommonResult<String> upload(@RequestParam("file") MultipartFile file) {
return qiniuService.upload(file);
}
}
四、测试
请求接口
我们可以看到文件已经上传至七牛云
并且图片可以正常显示
注意:
要使图片可以被访问,需要设置访问空间为公开
图片显示