Springboot+Vue实现使用七牛云对象存储服务的图片上传、获取和删除功能
·
这里仅列举一些关键的代码,供大家学习参考。
前端:
// 暴露用户头像删除与更新功能相关的api接口
export const UserPicDeleteAndUpdateService = (storePic, picUrl) => {
let params = new URLSearchParams()
let fileName = storePic.slice(36) // 截取文件名部分
params.append('fileName', fileName)
params.append('picUrl', picUrl)
return request.put('/delAndUpdate', params)
}
// 用户头像地址
const imgUrl= ref(userStore.userInfo.userPic ? userStore.userInfo.userPic : avatar)
// 数组:指定允许的图片类型
const allowedTypes = ['image/jpeg','image/png','image/webp','image/jpg']
// 文件上传前核验
const beforeAvatarUpload = (rawFile) => {
if (!allowedTypes.includes(rawFile.type)) {
ElMessage.error('文件非图片格式!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('图片大小不能超2MB!')
return false
}
return true
}
// 图片上传成功的回调函数
const uploadSuccess = (result) => {
// 回显图片内容
imgUrl.value = result.data
}
// 点击更新用户头像时调用的处理方法
const updateAvatar = async () => {
if (imgUrl.value === avatar) {
ElMessage.error('请先选择图片文件')
return
}
let result = await UserPicDeleteAndUpdateService(userStore.userInfo.userPic, imgUrl.value)// 删除上传的原用户头像并更新新头像
ElMessage.success(result.message ? result.message : '修改成功')
userStore.userInfo.userPic = imgUrl.value
}
<el-row>
<el-col :span="12">
<el-upload
ref="uploadRef"
class="avatar-uploader"
:show-file-list="false"
:auto-upload="true"
action="/api/upload"
name="file"
:headers="{'Authorization': tokenStore.token}"
:before-upload="beforeAvatarUpload"
:on-success="uploadSuccess"
>
<img v-if="imgUrl" :src="imgUrl" class="avatar" />
</el-upload>
<br />
<el-button type="primary" :icon="Plus" size="large" @click="uploadRef.$el.querySelector('input').click()">
选择图片
</el-button>
<el-button @click="updateAvatar" type="success" :icon="Upload" size="large">
更新头像
</el-button>
</el-col>
</el-row>
后端:
导入的七牛云相关的两个依赖
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.16.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>compile</scope>
</dependency>
工具类
@Component
public class QiniuUtil {
// 构造一个带指定 Region 对象的配置类
private static final Configuration cfg = new Configuration(Region.autoRegion());
private static final UploadManager uploadManager = new UploadManager(cfg);
// 上传凭证
private static String ACCESS_KEY;
private static String SECRET_KEY;
private static String BUCKET;
private static String DOMAIN;
// 默认不指定key的情况下,以文件内容的hash值作为文件名
// 凭证等信息配置在了yml配置文件中,这里获取值时不能在静态常量上直接通过@Value获取
@Value("${qiniu.accessKey}")
public void setAccessKey(String accessKey) {
ACCESS_KEY = accessKey;
}
@Value("${qiniu.secretKey}")
public void setSecretKey(String secretKey) {
SECRET_KEY = secretKey;
}
@Value("${qiniu.bucket}")
public void setBucket(String bucket) {
BUCKET = bucket;
}
@Value("${qiniu.domain}")
public void setDomain(String domain) {
DOMAIN = domain;
}
private static Auth auth;
private static BucketManager bucketManager;
public QiniuUtil(@Value("${qiniu.accessKey}") String ak, @Value("${qiniu.secretKey}") String sk) {
auth = Auth.create(ak, sk);
bucketManager = new BucketManager(auth, cfg);
}
public static String uploadFile(InputStream is, String fileName) {
try {
String upToken = auth.uploadToken(BUCKET);
Response response = uploadManager.put(is, fileName, upToken, null, null);
// response.bodyString():{"hash":"Fo7JxhrAagwtka2eVJeMJNjBBZNC","key":"f20a7ad4-64fa-4d30-b41d-84f17d67db4e.webp"}
// 图片url格式:你的domain/putRet.key
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
return DOMAIN + "/" + putRet.key;
} catch (QiniuException ex) {
ex.printStackTrace();
if (ex.response != null) {
System.err.println("ex.response:" + ex.response);
String body = ex.response.toString();
System.err.println("bode:" + body);
}
}
return "";
}
public static void delFile(String fileName) {
try {
bucketManager.delete(BUCKET, fileName);
} catch (QiniuException ex) {
// 如果遇到异常,说明删除失败,可以自行修改异常的处理逻辑
System.err.println("ex.code()" + ex.code());
System.err.println(ex.response.toString());
}
}
// 获取上传的所有文件名集合
public static List<String> getFiles() {
// 文件名前缀
String prefix = "";
// 每次迭代的长度限制,最大1000,推荐值 1000
int limit = 10;
// 指定目录分隔符,列出所有公共前缀(模拟列出目录效果)。缺省值为空字符串
String delimiter = "";
List<String> fileNames = new ArrayList<>();
// 列举空间文件列表
BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(BUCKET, prefix, limit, delimiter);
while (fileListIterator.hasNext()) {
// 处理获取的file list结果
FileInfo[] items = fileListIterator.next();
for (FileInfo item : items) {
fileNames.add(item.key);
/*item.key 文件名;item.hash ETag;item.fsize 文件大小;item.mimeType 文件类型*/
}
}
return fileNames;
}
}
响应实体类
// 统一响应结果
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result<T> {
private Integer code;// 业务状态码 1-成功 0-失败
private String message;// 提示信息
private T data;// 响应数据
// 快速返回操作成功响应结果(带响应数据)
public static <E> Result<E> success(E data) {
return new Result<>(1, "操作成功", data);
}
// 返回操作成功响应结果(带自定义的提示信息)
public static Result ok(String mes) {
return new Result(1, mes, null);
}
// 快速返回操作成功响应结果
public static Result success() {
return new Result(1, "操作成功", null);
}
public static Result error(String message) {
return new Result(0, message, null);
}
}
控制器类
@RestController
public class FileController {
@Autowired
private UserService userService;
@PostMapping("/upload")
public Result<String> upload(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();
String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
String avatarUrl = QiniuUtil.uploadFile(file.getInputStream(), fileName);
return Result.success(avatarUrl);
}
@PutMapping("/delAndUpdate")
public Result deleteAndUpdate(@RequestParam String fileName, @RequestParam String picUrl) {
String mes = "";
// 获取云存储空间中的文件名列表
List<String> files = QiniuUtil.getFiles();
if (files.isEmpty() || "".equals(fileName)) {
mes = "云存储空间是空的或存储的用户头像状态为空,不执行原头像删除;新用户头像已同步";
} else if (files.contains(fileName)){
QiniuUtil.delFile(fileName);
}
userService.updateAvatar(picUrl);
return Result.ok(mes);
}
}
更多推荐

所有评论(0)