SSM框架结合LayUi文件上传模块接入COS对象存储服务


简介

在日常项目开发中经常会用到图片,视频等文件存储的操作,但是文件如果一直存放在本地服务器中,可以会导致资源浪费,且访问速度也有所限制,这时我们就会考虑CDN加速云端存储等方式来解决问题,这里就要介绍下本文用到的COS对象存储-安全稳定、海量、便捷、低延迟、低成本的云端存储服务。

COS对象存储

对象存储(Cloud Object Storage,COS)是腾讯云提供的面向非结构化数据,支持 HTTP/HTTPS 协议访问的分布式存储服务,它能容纳海量数据并保证用户对带宽和容量扩充无感知,可以作为大数据计算与分析的数据池。腾讯云 COS 提供网页端管理界面、多种语言的 SDK 以及命令行和图形化工具,并且完全兼容 S3 的 API 接口,方便用户直接使用社区工具和插件,COS 还可以和其他云产品结合,比如利用 CDN 的全球节点提供加速服务,利用数据万象的图片处理能力提供一站式图片解决方案等(详细介绍)

案例实现

  • 本文使用的是腾讯云提供的COS服务,每个月提供50G存储容量,10G流量,对于一般的博客网站,以及项目测试来说绰绰有余
  • 腾讯云对象存储 COS 除了提供多种 API 接口,还提供了丰富多样的 SDK 供开发者使用,如Java、Python、Js等…,本项目后台基于SpringMVC实现,前端通过LayUi框架的文件上传模块结合实现
  • 存储桶相应的还有防盗链设置,跨域规则设置,读写权限设置,以及相应的CDN加速服务
    www.srblog.cn

代码

后台实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package cn.mall.controller.portal;

import cn.mall.common.ServerResponse;
import cn.mall.util.PropertiesUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/upload/")
public class UploadController {

//密钥请前往腾讯云后台查询
private static String secretId="*************";
private static String secretKey="*************";
private static String bucketName="你的存储桶名称";
private static String RegionName="存储桶所属地域";
/**
* 文件上传
* @param file
* @param session
* @return
*/

@RequestMapping(value = "upload_image_cos.do",method = RequestMethod.POST)
@ResponseBody
public Object Upload(@RequestParam(value = "file") MultipartFile file, HttpSession session){
if(file == null){
return new UploadMsg(0,"文件为空",null);
}
//获取文件上传原名
String oldFileName = file.getOriginalFilename();
String eName = oldFileName.substring(oldFileName.lastIndexOf("."));
//通过UUID随机生成新的文件名
String newFileName = UUID.randomUUID()+eName;

// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region(RegionName));
// 3 生成cos客户端
COSClient cosclient = new COSClient(cred, clientConfig);
// bucket的命名规则为{name}-{appid} ,此处填写的存储桶名称必须为此格式
String bucketName = this.bucketName;

// 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20 M 以下的文件使用该接口
// 大文件上传请参照 API 文档高级 API 上传
File localFile = null;
try {
//创建临时文件
localFile = File.createTempFile("temp",null);
file.transferTo(localFile);
// 指定要上传到 COS 上的路径
String key = PropertiesUtil.getProperty("cos_key_name")+newFileName;
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
return new UploadMsg(1,"上传成功", newFileName);
} catch (IOException e) {
return new UploadMsg(-1,e.getMessage(),null);
} finally {
// 关闭客户端(关闭后台线程)
cosclient.shutdown();
}
}

//自定义JSON消息体
private class UploadMsg {
public int status;
public String msg;
public String path;

public UploadMsg() {
super();
}

public UploadMsg(int status, String msg,String path){
this.status =status;
this.msg =msg;
this.path =path;
}
}

}
前台实现(完整表单)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>商品添加</title>
<link rel="stylesheet" href="../assets/layui/css/layui.css">

</head>
<body>
<form class="layui-form column-content-detail">

<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-form-item">
<label class="layui-form-label">商品标题:</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入商品标题" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分类:</label>
<div class="layui-input-block">
<select name="categoryId" lay-verify="required">
<option value="">请选择分类</option>
<option value="100001">家用电器</option>
<option value="100002">数码3C</option>
<option value="100003">服装箱包</option>
<option value="100004">食品生鲜</option>
<option value="100005">酒水饮料</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">图像上传:</label>
<div class="layui-input-block">
<img id="upload_img" src="../images/default_img.png" width="100" height="100">
<button type="button" class="layui-btn" id="test1">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">商品介绍:</label>
<div class="layui-input-block">
<textarea class="layui-textarea layui-hide" name="detail" lay-verify="detail" id="LAY_demo_editor"></textarea>
</div>
</div>
<input type="hidden" id="mainImage" name="mainImage" required value="default_img.png" class="layui-input">
<input type="hidden" id="status" name="status" value="1" class="layui-input">
<div class="layui-form-item">
<label class="layui-form-label">商品库存:</label>
<div class="layui-input-block">
<input type="text" name="stock" required lay-verify="number" placeholder="请输入商品库存" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">商品价格:</label>
<div class="layui-input-block">
<input type="text" name="price" required lay-verify="number" placeholder="请输入商品价格" autocomplete="off" class="layui-input">
</div>
</div>

</div>
</div>

<div class="layui-form-item" style="padding-left: 10px;">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="add_product">立即提交</button>
<button id="reset" type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<script src="../js/cos-js-sdk-v5.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/jquery-1.10.2.js" type="text/javascript" charset="utf-8"></script>
<script src="../assets/layui/layui.all.js"></script>
<script>
layui.use(['form', 'jquery', 'laydate', 'layer', 'laypage', 'element', 'upload', 'layedit'], function() {
var form = layui.form,
layer = layui.layer,
$ = layui.jquery,
laypage = layui.laypage,
laydate = layui.laydate,
layedit = layui.layedit,
element = layui.element,
upload=layui.upload;

//创建一个编辑器
var editIndex = layedit.build('LAY_demo_editor', {
tool: ['strong' //加粗
, 'italic' //斜体
, 'underline' //下划线
, 'del' //删除线
, '|' //分割线
, 'left' //左对齐
, 'center' //居中对齐
, 'right' //右对齐
, 'link' //超链接
, 'unlink' //清除链接
, 'image' //插入图片
],
height: 100
});

var uploadInst = upload.render({
elem: '#test1' //绑定元素
,url:'../upload/upload_image_cos.do'//后台上传接口
,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
layer.msg('上传中',{icon: 16,time:0,shade:0.01});
}
,done: function(res, index, upload){
layer.closeAll('loading');
//status=1代表上传成功
if(res.status == 1){
layer.msg("上传成功",{icon:1});
//do something (比如将res返回的图片链接保存到表单的隐藏域)
$('#upload_img').attr('src','https://sr-1251242863.cos.ap-shanghai.myqcloud.com/webdemo/images/'+res.path);
$('#mainImage').val(res.path);
}

//获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
var item = this.item;
//文件保存失败
//do something
}
,error: function(){
layer.closeAll('loading');
//请求异常回调
layer.msg("上传失败,请重试",{icon:2});
}
,size:2048 //文件大小限制
,number:1 //文件数量限制
,accept: 'images' //文件类型限制
,acceptMime: 'image/jpg, image/png' //选择窗口属性
});
});
</script>
</body>
</html>

动图演示

www.srblog.cn

sr wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
0%