方式1.当前项目所在的服务器。但是不太好,有很多的问题
问题一:会占用tomcat的硬盘空间,影响tomcat的运行效率;
问题二:用户上传的文件容易丢失(clean,会把target删除)
问题三:在集群环境下会产生数据的不一致。(上传头像上传的只是某一台服务器)
方式2.上传到专门的文件存储服务器,tomcat就是应用服务器,来部署应用的
2.1FASTDFS、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());
- }
- }
检查七牛云,文件确实被删除了
这个工具类有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>
在页面上效果如下
选择完头像点击确定就会执行这样一段代码:
- @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>