springboot+vue+腾讯云cos实现更改头像
基于y总的springboot框架课,课上没有实现用户自定义上传图片作为头像,每个用户都是一个头像属实受不了,再加上咱自己博客图片都是用腾讯云cos存储图片(阿里云oos一样)有一定经验就自己照葫芦画瓢写了一个,主要流程就是:
前端传一个头像后->调用后端接口->后端调用腾讯云cos接口->返回一个链接->更新数据库->前端接受到图片链接后更新全局变量photo实现无刷更新
最终效果:
接下来是一些笔记:
Maven添加依赖
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.103</version>
</dependency>
配置腾讯云cos
初始化信息:COSProperties.java
@Data
@ConfigurationProperties
public class COSProperties {
// 初始化用户身份信息 前往密钥管理查看
private String secretId = "";
// 初始化用户身份信息 前往密钥管理查看
private String secretKey = "";
// 指定要上传到的存储桶
private String bucketName = "";
//指定要上传的地区名称 去控制台查询
private String regionName = "";
}
客户端配置: COSClientConf.java
@Configuration
@EnableConfigurationProperties(COSProperties.class)
public class COSClientConfig {
@Autowired
private COSProperties cosProperties;
@Bean
public COSClient cosClient(){
// 1 初始化用户身份信息(secretId, secretKey)。
// String secretId = "AKIDcKlIXWKgy3vc4Jj9tNblgW8UaPJxpZj8";
// String secretKey = "MUPecJmyuZzVs36vU8VeWLuCC5hPHxSS";
COSCredentials cred = new BasicCOSCredentials(cosProperties.getSecretId(),cosProperties.getSecretKey());
// 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
Region region = new Region(cosProperties.getRegionName());
ClientConfig clientConfig = new ClientConfig(region);
// 3 生成 cos 客户端。
COSClient cosClient = new COSClient(cred, clientConfig);
return cosClient;
}
}
然后写一个上传图片的接口
public interface PhotoService {
public String uploadImage(MultipartFile file);
}
实现接口
@Service
@Slf4j
public class PhotoServiceImpl implements PhotoService {
String key;
@Autowired
private UserMapper userMapper;
@Autowired
private COSClient cosClient;
@Autowired
private COSProperties cosProperties;
// 支持的文件类型
private static final List<String> suffixes = Arrays.asList("image/png", "image/jpeg");
@Override
public String uploadImage(MultipartFile file) {
UsernamePasswordAuthenticationToken authenticationToken =
(UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal();
User user = loginUser.getUser();
try {
// 1、图片信息校验
// 1)校验文件类型
String type = file.getContentType(); //获取文件格式
if (!suffixes.contains(type)) {
return "上传失败,文件类型不匹配:"+type;
}
// 2)校验图片内容
BufferedImage image = ImageIO.read(file.getInputStream());
if (image == null) {
return "上传失败,文件内容不符合要求";
}
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(type);
UUID uuid = UUID.randomUUID();
// 指定要上传到 COS 上对象键 此key是文件唯一标识
key = uuid.toString().replace("-","")+".jpg";
PutObjectRequest putObjectRequest = new PutObjectRequest(cosProperties.getBucketName(), key, file.getInputStream(),objectMetadata);
//使用cosClient调用第三方接口
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
log.info(putObjectRequest+"");
//返回路径
}catch (Exception e){
e.printStackTrace();
}
//拼接返回路径
String imagePath = "https://cos.zinzin.cc/"+ key + "?imageMogr2/format/webp";
//把个人的照片更新
User new_user = new User(
user.getId(),
user.getUsername(),
user.getPassword(),
imagePath,
user.getRating(),
user.getOpenid()
);
userMapper.updateById(new_user);
return imagePath;
}
}
控制层:PhotoControll.java
@RestController
@Slf4j
public class PhotoController {
@Autowired
private PhotoService photoService;
@PostMapping("/api/user/account/upload_photo/")
public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file){
String url= photoService.uploadImage(file);
log.info("返回地址:【{}】",url);
return ResponseEntity.ok(url);
}
}
这里可以提前拿postman测试下
从上面可以看到后端是成功上传到cos并且返回了一个图片的链接。
前端部分
这边是把input和头像放在一个label里面把input隐藏,实现点击图片选择文件的操作
<div class="card-body">
<label class="img1" for="file">
<input type="file" style="display: none;" class="form-control" id="file"
@click="upload_photo()" />
<img :src="$store.state.user.photo" alt="" style="width: 100%;">
</label>
<hr>
<button style="display: flex; justify-content: center; width: 100%;" id="upload"
class="btn btn-light" type="button" @click="upload_photo()">点击头像更新</button>
</div>
然后将文件转换成formData在通过ajax传给后端,成功后通过updataPhoto更新photo地址
const upload_photo = () => {
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
url: "https://snake.zinzin.cc/api/user/account/upload_photo/",
type: "POST",
cache: false,
data: formData,
processData: false,
contentType: false,
headers: {
Authorization: "Bearer " + store.state.user.token,
},
success(resp) {
console.log(resp);
store.commit("updatePhoto", resp);
},
error(resp) {
console.log(resp);
}
})
}
以上主要是对主要的流程的一个梳理笔记,经供参考~
参考文献
//SpringBoot整合腾讯云COS对象存储实现文件上传
https://blog.csdn.net/qq_40087415/article/details/122027162
//通过Ajax方式上传文件,使用FormData进行Ajax请求
https://blog.csdn.net/Inuyasha1121/article/details/51915742
//腾讯云Cos接口官方文档
https://cloud.tencent.com/document/product/436/10199
评论区