上传的文件保存到哪里好
方式1.保存当前项目所在的服务器。但是不太好
问题一:会占用tomcat的硬盘空间,影响tomcat的运行效率;
问题二:用户上传的文件容易丢失(clean,会把target删除)
问题三:在集群环境下会产生数据的不一致。(上传头像上传的只是某一台服务器)
方式2.上传到专门的文件存储服务器,tomcat就是应用服务器,来部署应用的
2.1 FASTDFS、HDFS 要自己搭建
2.2 购买第三方云存储:
阿里云、百度云、腾讯云、七牛云(视觉方面做的极致,视频、图片)
使用七牛云提供的对象存储服务来存储图片
注册并登录成功以后:
第一步:创建对象存储空间
在资源管理里点击新建存储空间
此时弹出页面:填好信息
可以创建多个存储空间,各个存储空间是相互独立的
第二步:查看存储空间信息
存储空间创建后,会在左侧的存储空间列表菜单中展示创建的存储空间名称,点击存储空间名称可以查看当前存储空间的相关信息
切换tab页到-文件管理
七牛云开发者中心
可以通过七牛云提供的开发者中心学习如何操作七牛云服务,地址:七牛开发者中心
对象存储 - 七牛开发者中心 点击对象存储,跳转到对象存储开发页面
写一个入门案例:
第一步:导入jar包:
<!--七牛云服务平台,第三方服务(图片上传)-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
第二步:鉴权
我们的AK和SK在哪呢?
一会在Java代码里会用到这一对AK、SK的,到时候来这里复制就好了
文件上传:
在官网里是有案例的,我这里就是仿照那里写的测试代码
public void testUpload(){
//构造一个带指定 Zone 对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//创建一个文件上传的管理器对象
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
//你自己的AccessKey
String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
//你自己的SecretKey
String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
//你自己的空间的名字
String bucket = "shfxa0328-xym";
//如果是Windows情况下,格式是 D:\\qiniu\\test.png
String localFilePath = "D:/qiniu/test.jpg";
///key表示文件上传到七牛云中的名字,默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
//鉴权
Auth auth = Auth.create(accessKey, secretKey);
//创建一个文件上传标示token
String upToken = auth.uploadToken(bucket);
try {
//文件上传
Response response = uploadManager.put(localFilePath, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
运行之前先施法,配置一下这里
运行,控制台打印如下
在七牛云上可以看到我们上传图片成功了,且文件名和我们控制台打印的结果是一样的
点击右边的文件详情,就可以看到这个文件的据图信息了
文件的删除
public void testDelete(){
//构造一个带指定 Zone 对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//你自己的AccessKey
String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
//你自己的SecretKey
String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
//你自己的空间的名字
String bucket = "shfxa0328-xym";
//要删除的那个文件的名称
String key = "FnATf109bsayb0tYiZKgoHn96lQT";
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());
}
}
检查七牛云,文件确实被删除了
封装工具类QiniuUtils
这个工具类有3处是需要修改的
public class QiniuUtils {
private static String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
private static String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
private static String bucket = "shfxa0328-xym";
public static void upload2Qiniu(String filePath,String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
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
}
}
}
//上传文件
public static void upload2Qiniu(byte[] bytes, String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//默认不指定key的情况下,以文件内容的hash值作为文件名
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);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
//删除文件
public static void deleteFileFromQiniu(String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
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());
}
}
public static String getUrl(String uuidName) {
return "http://rejg8ksr8.hn-bkt.clouddn.com/" + uuidName;
}
}
实现一个上传头像的功能
在前台页面上效果如下:
前端页面:
<form id="ec" th:action="@{/admin/upload/{id}(id=${id})}" method="post" enctype="multipart/form-data" class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">上传头像:</label>
<div class="col-sm-10">
<input type="file" name="file" id="file" class="form-control" readonly/>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2 text-right">
<button class="btn btn-primary" type="submit">确定</button>
<button class="btn btn-white" type="button" onclick="javascript:opt.closeWin();" value="取消">取消</button>
</div>
</div>
选择完头像点击确定就会执行这样一段后台的Java代码
@PostMapping("/upload/{id}")
public String upload(@PathVariable("id") Long id, @RequestParam("file") MultipartFile multipartFile, Model model) throws IOException {
//id是用户的id
//1. 将图片上传到七牛云
//生成一个唯一的文件名
String originalFilename = multipartFile.getOriginalFilename();
String uuidName = FileUtil.getUUIDName(originalFilename);
QiniuUtils.upload2Qiniu(multipartFile.getBytes(),uuidName);
//2. 将图片信息保存到数据库
//2.1 获取图片的url
String headUrl = QiniuUtils.getUrl(uuidName);
//2.2 封装信息到Admin
Admin admin = new Admin();
admin.setId(id);
admin.setHeadUrl(headUrl);
//2.3 更新admin
adminService.update(admin);
//3. 显示成功页面
return successPage(model,"上传头像成功");
}
在数据库的acl_admin表中head_url字段确实变更了
去七牛云里,也是可以看到我们上传成功的头像的
要注意的点:一定要在spring-mvc的配置文件中开启文件上传解析器
<!--文件解析器-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定文件上传的最大值为100MB,100*1024*1024 -->
<property name="maxUploadSize" value="104857600" />
<!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
<property name="maxInMemorySize" value="4096" />
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>