目录
一、七牛云起步
二、代码实战
1、引入依赖
2、AK、SK和bucket name
3、代码实现
4、容易出问题的点
5、前端传递数据
三、总结
在我们实际的项目中,经常会将服务器进行划分,比如:专门运行我们程序的应用服务器、专门运行我们数据库的数据库服务器、还有负责文件存储的文件服务器、负责视频存储的服务器。
这些服务器组成我们的所有服务、各司其职,这样划分的目的相比大家也知道,减轻一台服务器服务器的压力。
当用户请求我们应用应用服务器的时候,由我们的应用再分别访问我们数据库服务器、文件存储服务器等,最后将请求的资源返回给我们的用户,这样构成整个应用的请求过程。
在后端开发中,图片上传是一个很常见的功能,由前端将图片信息传递给后端,后端将其重新命名并且上传到服务器进行储存,以保证其他用户也可以访问到此图片,这里我们使用七牛云的对象存储来储存图片。
这是七牛云的主页面,可以在这里进行账号的注册以及登录。
然后点击控制台进入控制台界面
进入之后点击左上角,进入对象储存Kodo(这里我是已经购买过对象储存服务器,界面可能会不同)
点击空间管理,然后点击新建空间,就可以创建自己的储存空间了
空间的创建可以创建多个,各个空间之间互不影响,互相独立。
这里我们使用的是七牛云提供的操作对象服务,使用的是Java SDK的方式,详情可以前往开发者中心查看
首先在开始之前我们需要先引入我们需要的依赖(此处我们引入七牛云存储的 Java SDK,用于在 Java 项目中使用七牛云的存储服务以及Google 的 Gson 库,用于在 Java 项目中进行 JSON 数据的序列化和反序列化)
com.qiniu
qiniu-java-sdk
[7.13.0, 7.13.99]
com.google.code.gson
gson
2.8.5
compile
在使用七牛云服务时我们是需要进行认证的,其中AK和SK也就是AccessKey/SecretKey
bucket name则我们创建的储存空间的名字
AK和SK可以在密钥管理里面找到
我们可以根据开发者中心的文档封装一个工具类
package com.test5.test.util;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
public class UploadUtil {
// 填写accessKey值
public static String accessKey = "your accessKey";
// 填写secretKey 值
public static String secretKey = "your secretKey";
// 填写bucket name值
public static String bucket = "your bucket name";
/**
* 上传文件
* @param filePath 文件路径
* @param fileName 文件名
*/
public static void uploadFile(String filePath,String fileName){
Configuration cfg = new Configuration(Zone.zoneNa0());
UploadManager uploadManager = new UploadManager(cfg);
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(filePath, fileName, upToken);
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
} catch (QiniuException ex) {
Response r = ex.response;
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
/**
* 上传文件
* @param bytes 文件字节数组
* @param fileName 文件名
*/
public static String uploadFile(byte[] bytes, String fileName){
Configuration cfg = new Configuration(Zone.zoneNa0());
UploadManager uploadManager = new UploadManager(cfg);
String key = fileName;
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(bytes, key, upToken);
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
} catch (QiniuException ex) {
return "上传失败!";
}
return "上传成功";
}
/**
* 删除文件
* @param fileName 文件名
*/
public static void deleteFile(String fileName){
Configuration cfg = new Configuration(Zone.zoneNa0());
String key = fileName;
Auth auth = Auth.create(accessKey, secretKey);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
bucketManager.delete(bucket, key);
} catch (QiniuException ex) {
System.err.println(ex.code());
System.err.println(ex.response.toString());
}
}
}
然后我们需要写一个测试使用的接口
package com.test5.test.controller;
import com.test5.test.util.UploadUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
@RestController
@RequestMapping(value = "/upload")
public class uploadController {
@PostMapping("/uploadImage")
public String Upload(@RequestParam("imgFile")MultipartFile imgFile) throws IOException {
//获取原始文件名
String originalFilename = imgFile.getOriginalFilename();
//获取图片名后缀
String ext = "." + originalFilename.split("\\.")[1];
//使用UUID生成图片名,防止名称一样
UUID id=UUID.randomUUID();
String idd=id.toString().split("-")[0];//生成8位数长度的随机十六进制
String fileName = idd.toString().replace("-","") + ext;
String returnName = UploadUtil.uploadFile(imgFile.getBytes(),fileName); //图片上传成功
if(returnName.equals("上传成功")){
return fileName;
}
return returnName;
}
}
在使用的过程中很有可能会出现以下报错
{"error":"incorrect region, please use up-na0.qiniup.com, bucket is: sc-picture"}
这是因为你的地域选择错了(此位置你要根据你自己的创建的储存空间的地区进行变化)
解决办法:
/**
* 构造一个带指定Zone对象的配置类
* 华东 : Zone.zone0()
* 华北 : Zone.zone1()
* 华南 : Zone.zone2()
* 北美 : Zone.zoneNa0()
*/
//指定上传文件服务器地址:
Configuration cfg = new Configuration(Zone.zoneNa0());
我们这里使用的是工具类里面的第二个方法,也就是文件字节数组
微信小程序作为前端进行图片上传
/**
* 添加图片
*/
addPicture() {
//从相册获取照片
wx.chooseMedia({
count: 1,
mediaType: ['image', 'video'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
const tempFilePaths = res.tempFiles[0].tempFilePath
console.log("图片临时路径:"+tempFilePaths)
wx.uploadFile({
url: 'http://localhost:9999/upload/uploadImage', // 请求的后端接口URL
filePath: tempFilePaths,// 图片文件的临时路径
name: 'imgFile',// 后端接口接收的字段名
header: {
'Content-Type': 'multipart/form-data',// 设置请求头为 multipart/form-data
},
success(res) {
console.log("网络访问路径:"+res.data);// 上传成功后的处理
},
fail(error) {
console.error(error); // 上传失败后的处理
}
});
}
})
},
vue作为前端上传
html:
确 定
js
submitForm(formName) {
this.$refs[formName].validate((valid) => {
//校验成功
if (valid) {
let myfile = this.$refs.upload
let files = myfile.files
let file = files[0]
let formdata = new FormData() //formdata格式
formdata.append("picture", file) //图片文件
formdata.append('name', this.product_add.name) //其他参数
formdata.append('introduce', this.product_add.introduce) //其他参数
// 发送请求
this.axios({
method: 'POST',
data: formdata,
url: '/product_Description/product/addProduct',
headers: {'Content-Type': 'multipart/form-data'}
}).then((response) => {
this.initProduct()
if(resp.data.code == 0){
this.$message({
message: '添加产品成功!',
type: 'success'
});
}else{
this.$message.error('添加产品失败!');
}
})
}
});
},
这是小编第一次自己做后端的图片上传功能,中途磕磕绊绊的遇到了很多问题,现在记录一下帮大家避坑呀,各位可以在我给出的代码上进行进一步的优化,比如加入redis对缓存进行进一步的处理,OK,那今天的分享结束了,咱们下期再见咯!