spring-boot集成七牛云实现图片上传与下载
文档 https://developer.qiniu.com/sdk#official-sdk
环境:spring-boot 2.5.1 七牛云sdk 7.7.0
前置条件
- 注册七牛云账号
- 创建对象存储空间
- 如果空间是公开的,访问文件时,不需要认证,直接get文件url即可
- 如果空间是私有的,访问文件时,需要进行认证
一般使用公开的空间,因为需要提供内容供用户访问。
开始集成
添加依赖
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.7.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
添加配置
oss:
qiniu:
domain: xxxxxa7om.hn-bkt.clouddn.com # 访问域名(默认使用七牛云测试域名)
accessKey: XiAbXQnW1DgH-MC6QVXds_etJcLim4cPZ52xxxxx # 公钥
secretKey: iZ2daBzj5XgmIX1rJjcgLUY0QMiqphxZk_9xxxxx # 私钥
bucketName: blog-lyp #存储空间名称
创建配置类,方便获取配置信息
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "oss.qiniu")
@Data
public class QiniuProperties
{
private String domain; // CDN域名
private String accessKey; // ACCESS_KEY
private String secretKey; // SECRET_KEY
private String bucketName; // 空间名称
}
创建TextUtils工具类,用于生成UUID格式的文件名称,或者从图片URL中提取Key
public class TextUtils
{
// 根据文件名,生成UUID作为新的文件名
public static String generateFileName(String filename)
{
Objects.requireNonNull(filename,"文件名为null");
int index=filename.lastIndexOf('.');
if(filename.isBlank() || index==-1)
{
throw new IllegalArgumentException("文件名不合法");
}
String suffix=filename.substring(index);
String uuid= UUID.randomUUID().toString().replaceAll("-","");
return uuid+suffix;
}
// 从图片URL中提取Key
// http://quwf2a7om.hn-bkt.clouddn.com/xxx/11c85acc16f24361ba97999185fb0469.jpeg
public static String getKey(String imageUrl)
{
if(imageUrl==null || imageUrl.trim().isEmpty())
{
return null;
}
return imageUrl.substring(imageUrl.indexOf(".com")+5);
}
}
上传图片
创建上传表单,表单提交时,form必须设置属性 enctype="multipart/form-data"
创建七牛云Service接口
public interface QiniuService
{
String uploadImage2qiniu(InputStream in,String key);
}
Service实现类
@Service
public class QiniuServiceImpl implements QiniuService
{
private final String domain;
private final String bucketName;
// 七牛文件上传管理器
private final Configuration cfg;
private final Auth auth;
@Autowired
public QiniuServiceImpl(QiniuProperties oss)
{
String ak = oss.getAccessKey();
String sk = oss.getSecretKey();
this.domain = oss.getDomain(); // CDN域名
this.bucketName = oss.getBucketName();
// //构造一个带指定 Region 对象的配置类
cfg = new Configuration(Region.huanan());
auth = Auth.create(ak,sk);
}
/**
* 上传图片到七牛云
* @return 图片url
* */
@Override
public String uploadImage2qiniu(InputStream in,String key)
{
try {
UploadManager uploadManager = new UploadManager(cfg);
// 根据命名空间生成的上传token
String upToken = auth.uploadToken(bucketName);
Response response = uploadManager.put(in,key,upToken,null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
//System.out.println(putRet.key);
//System.out.println(putRet.hash);
return String.format("http://%s/%s",this.domain,putRet.key);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
return null;
}
}
在Controller中调用Service中的方法,上传图片,成功后返回图片url
@Controller
public class QiniuController
{
private final QiniuService qiniuService;
@Autowired
public QiniuController(QiniuService qiniuService)
{
this.qiniuService = qiniuService;
}
@PostMapping("/image/upload")
@ResponseBody
public String uploadImage(@RequestParam("file")MultipartFile file) throws IOException
{
if(!file.isEmpty())
{
InputStream in = file.getInputStream();
String filename = file.getOriginalFilename();
try
{
String key = "xxx/"+ TextUtils.generateFileName(filename);
String imageUrl = qiniuService.uploadImage2qiniu(in,key);
if(imageUrl!=null)
{
return "上传成功: "+imageUrl;
}
}
catch(IllegalArgumentException e)
{
e.printStackTrace();
}
}
return "上传失败";
}
}
下载图片
如果是公开空间的话,访问图片时,直接get上传图片时返回的url即可。
如果是私有空间的话,需要使用相关API,提供身份认证信息进行访问。具体参考文档。
删除图片
在Service接口中添加方法
boolean deleteImageFromQiniu(String key);
在Service实现类中
/**
* 删除图片
* */
@Override
public boolean deleteImageFromQiniu(String imageUrl)
{
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
String key=TextUtils.getKey(imageUrl);
Response response = bucketManager.delete(bucketName,key);
return response.isOK();
} catch (QiniuException ex) {
//如果遇到异常,说明删除失败
System.err.println(ex.code());
System.err.println(ex.response.toString());
}
return false;
}
然后,在Controller中,调用删除方法
@DeleteMapping("/image/delete")
@ResponseBody
public String deleteImage(@RequestParam("image")String imageUrl)
{
boolean deleted = qiniuService.deleteImageFromQiniu(imageUrl);
if(deleted)
{
return "删除成功";
}
return "删除失败";
}

浙公网安备 33010602011771号