文章目录
- 概要
- 依赖
- 配置属性
- 配置类
- 配置文件
- 业务层
- 控制层
- 运行结果
- 亮点
概要
七牛存储很便宜的,在使用项目的用好官方封装好的sdk,结合springboot去使用很方便,我本地用的是springoot3+spring-boot-autoconfigure
依赖
<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.18.0</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
配置属性
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** @author*/
@Data
@Slf4j
@ConfigurationProperties(prefix = "cc.qiniu")
public class QiNiuProperties {/*** host*/private String accessKey;/*** apiKey*/private String secretKey;/*** bucket*/private String bucket;/*** domain*/private String domain;}
配置类
import com.cc672cc.properties.QiNiuProperties;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class QiNiuConfig {@Autowiredprivate QiNiuProperties qiNiuProperties;@Beanpublic Auth auth() {return Auth.create(qiNiuProperties.getAccessKey(), qiNiuProperties.getSecretKey());}@Beanpublic com.qiniu.storage.Configuration configuration() {// todo 这里换上你自己的区域return new com.qiniu.storage.Configuration(Region.huadong());}@Beanpublic UploadManager uploadManager(com.qiniu.storage.Configuration cfg) {return new UploadManager(cfg);}@Beanpublic com.qiniu.storage.BucketManager bucketManager(com.qiniu.storage.Configuration cfg, Auth auth) {return new com.qiniu.storage.BucketManager(auth, cfg);}
}
配置文件
cc:qiniu:access-key: 你的access-keysecret-key: 你的secret-keybucket: 你自己的bucket名字domain: 写上你自己的七牛存储访问的域名,系统自带的30天会过期,尽快绑定
业务层
public interface IQiNiuService {String uploadFile(MultipartFile file) throws IOException;String uploadFile(String filePath, String key) throws IOException;void deleteFile(String key) throws IOException;
}
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import com.cc672cc.properties.QiNiuProperties;
import com.cc672cc.service.IQiNiuService;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;@Service
@Slf4j
public class QiNiuServiceImpl implements IQiNiuService {@Autowiredprivate UploadManager uploadManager;@Autowiredprivate BucketManager bucketManager;@Autowiredprivate Auth auth;@Autowiredprivate QiNiuProperties qiNiuProperties;// 图片文件扩展名列表private static final List<String> IMAGE_EXTS = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "webp", "svg");// 视频文件扩展名列表private static final List<String> VIDEO_EXTS = Arrays.asList("mp4", "avi", "mov", "wmv", "flv", "mkv", "webm");/*** 上传文件到七牛云*/@Overridepublic String uploadFile(MultipartFile file) throws IOException {String originalFilename = file.getOriginalFilename();String key = generateHierarchicalKey(originalFilename);try {Response response = uploadManager.put(file.getBytes(), key, getUploadToken());DefaultPutRet putRet = response.jsonToObject(DefaultPutRet.class);return qiNiuProperties.getDomain() + "/" + putRet.key;} catch (QiniuException e) {Response r = e.response;throw new IOException("上传失败: " + r.toString(), e);}}/*** 上传本地文件到七牛云*/@Overridepublic String uploadFile(String filePath, String key) throws IOException {if (key == null) {// 从文件路径中提取文件名String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);key = generateHierarchicalKey(fileName);}try {Response response = uploadManager.put(filePath, key, getUploadToken());DefaultPutRet putRet = response.jsonToObject(DefaultPutRet.class);return qiNiuProperties.getDomain() + "/" + putRet.key;} catch (QiniuException e) {Response r = e.response;throw new IOException("上传失败: " + r.toString(), e);}}/*** 生成带层级结构的文件键* 格式: {type}/{yyyy-MM-dd}/{random}*/private String generateHierarchicalKey(String originalFilename) {if (originalFilename == null) {return UUID.randomUUID().toString().replace("-", "");}// 获取文件扩展名String ext = getFileExtension(originalFilename).toLowerCase();// 确定文件类型目录String typeDir = getFileTypeDir(ext);// 获取当前日期目录String dateDir = DateUtil.format(new Date(), "yyyy-MM-dd");// 生成随机文件名String randomName = UUID.randomUUID().toString().replace("-", "");// 组合完整路径return typeDir + "/" + dateDir + "/" + randomName + "." + ext;}/*** 获取文件扩展名*/private String getFileExtension(String filename) {int dotIndex = filename.lastIndexOf('.');if (dotIndex == -1) {return "";}return filename.substring(dotIndex + 1);}/*** 根据文件扩展名确定文件类型目录*/private String getFileTypeDir(String ext) {if (IMAGE_EXTS.contains(ext)) {return "images";} else if (VIDEO_EXTS.contains(ext)) {return "videos";} else {return "others";}}/*** 删除七牛云存储的文件** @param key 文件键* @throws IOException 删除失败时抛出异常*/@Overridepublic void deleteFile(String key) throws IOException {try {bucketManager.delete(qiNiuProperties.getBucket(), key);} catch (QiniuException e) {Response r = e.response;throw new IOException("删除失败: " + r.toString(), e);}}/*** 生成私有空间文件的临时访问URL** @param key 文件键* @param expireSeconds 过期时间(秒)* @return 临时访问URL*/public String generatePrivateDownloadUrl(String key, long expireSeconds) {return auth.privateDownloadUrl(qiNiuProperties.getBucket() + "/" + key, expireSeconds);}/*** 获取上传凭证*/private String getUploadToken() {return auth.uploadToken(qiNiuProperties.getBucket());}/*** 获取带回调的上传凭证*/public String getUploadTokenWithCallback(String callbackUrl, String callbackBody) {return auth.uploadToken(qiNiuProperties.getBucket(), null, 3600, new StringMap().put("callbackUrl", callbackUrl).put("callbackBody", callbackBody));}
}
控制层
@RestController
@Slf4j
@Tag(name = "开放七牛控制器", description = "测试接口")
@RequestMapping("/open/qiniu")
public class OpenQiNiuController {@Autowiredprivate IQiNiuService qiNiuService;@PostMapping("/upload")@Operation(summary = "上传文件")public String upload(@RequestParam("file") MultipartFile file) throws IOException {return qiNiuService.uploadFile(file);}
}
运行结果
{"code": 0,"message": "success","data": "http://qiniu.cc672.xyz/images/2025-06-17/0617cd177f264f938f7666b95a8698cf.jpg"
}
亮点
- 快捷
- 自定义三级目录