赞
踩
目录
在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
文件服务器:负责存储用户上传文件的服务器
分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。
常见的图片存储方案:
方案一:使用nginx搭建图片服务器
方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等
方案三:使用云存储,例如阿里云、==七牛云==等
七牛云(隶属于上海七牛信息技术有限公司)是国内领先的以视觉智能和数据智能为核心的企业级云计算服务商,同时也是国内知名智能视频云服务商,累计为 70 多万家企业提供服务,覆盖了国内80%网民。围绕富媒体场景推出了对象存储、融合 CDN 加速、容器云、大数据平台、深度学习平台等产品、并提供一站式智能视频云解决方案。为各行业及应用提供可持续发展的智能视频云生态,帮助企业快速上云,创造更广阔的商业价值。
1.注册、登录
要使用七牛云的服务,首先需要注册成为会员。地址:七牛云开发者平台
2.新建存储空间
3.查看存储空间信息
Java SDK的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对==有效的Access Key和Secret Key==,这对密钥可以在七牛云管理控制台的个人中心(七牛云开发者平台)获得,如下图:
可以通过七牛云提供的开发者中心学习如何操作七牛云服务,代码测试
地址:七牛开发者中心
shf-parent添加依赖管理
- <!--七牛云服务平台,第三方服务(图片上传)-->
- <dependency>
- <groupId>com.qiniu</groupId>
- <artifactId>qiniu-java-sdk</artifactId>
- <version>7.2.0</version>
- </dependency>
common-util引入依赖
- <!--七牛云服务平台,第三方服务(图片上传)-->
- <dependency>
- <groupId>com.qiniu</groupId>
- <artifactId>qiniu-java-sdk</artifactId>
- </dependency>
- package com.atguigu.test;
-
- 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;
- import org.junit.Test;
-
- public class TestQiniu {
-
- // 上传本地文件
- @Test
- public void uploadFile(){
- //构造一个带指定Zone对象的配置类
- Configuration cfg = new Configuration(Zone.zone2());
- //...其他参数参考类注释
- UploadManager uploadManager = new UploadManager(cfg);
- //...生成上传凭证,然后准备上传
- String accessKey = "***";
- String secretKey = "***";
- String bucket = "shf-img1";
- //如果是Windows情况下,格式是 D:\\qiniu\\test.png,可支持中文
- String localFilePath = "C:/Users/Plisetsky/Pictures/Saved Pictures/test.jpg";
- //默认不指定key的情况下,以文件内容的hash值作为文件名
- String key = "test.jpg";
- Auth auth = Auth.create(accessKey, secretKey);
- 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 e) {
- e.printStackTrace();
- }
- }
- }
-
- // 删除空间中的文件
- @Test
- public void deleteFile() {
- //构造一个带指定Zone对象的配置类
- Configuration cfg = new Configuration(Zone.zone2());
- //...其他参数参考类注释
- String accessKey = "***";
- String secretKey = "***";
- String bucket = "shf-img1";//空间
- String key = "test.jpg";//文件名称
- 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.atguigu.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 QiniuUtils {
- //设置ak,sk
- public static String accessKey = "***";
- public static String secretKey = "***";
- public static String bucket = "shf-img1";
-
- 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());
- }
- }
- }
SpringMVC 默认集成 Common-upload,可以直接整合
依赖管理
<commons-fileupload.version>1.3.1</commons-fileupload.version>
- <!-- 文件上传组件 -->
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>${commons-fileupload.version}</version>
- </dependency>
util 添加依赖
- <!-- 文件上传组件 -->
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- </dependency>
在spring-mvc添加配置
- <!--配置上传解析器
- "maxUploadSize":表示文件大小,图片的大小
- "maxInMemorySize" :图片加载到内存当中的大小 长 * 宽 * 像素字节数(argb8888,rgb565,argb4444)
- "defaultEncoding":UTF-8
- 优秀程序员:CV战士
- -->
- <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>
- $(function(){
- //表示房源图片
- $("#upload1").on("click",function(){
- opt.openWin('/houseImage/uploadShow/[[${house.id}]]/1','上传房源图片',580,430);
- });
- //表示房产图片
- $("#upload2").on("click",function(){
- opt.openWin('/houseImage/uploadShow/[[${house.id}]]/2','上传房产图片',580,430);
- });
- //上传首页默认图片
- $("#upload3").on("click",function(){
- opt.openWin('/houseImage/uploadShow/[[${house.id}]]/3','上传首页默认图片',580,430);
- });
- <div class="row">
- <div class="col-sm-12">
- <div class="ibox float-e-margins">
- <div class="ibox-title">
- <h3>房源图片信息</h3>
- <a class="btn btn-xs btn-primary" id="upload1">上传房源图片</a>
- </div>
- <div class="ibox-content">
- <a th:each="item,it : ${houseImage1List}" class="fancybox" >
- <img alt="image" th:src="${item.imageUrl}"/>
- <a th:attr="data-id=${item.id}" class="deleteImages1">删除</a>
- </a>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row">
- <div class="col-sm-12">
- <div class="ibox float-e-margins">
- <div class="ibox-title">
- <h3>房产图片信息</h3>
- <a class="btn btn-xs btn-primary" id="upload2">上传房产图片</a>
- </div>
- <div class="ibox-content">
- <a th:each="item,it : ${houseImage2List}" class="fancybox" >
- <img alt="image" th:src="${item.imageUrl}"/>
- <a th:attr="data-id=${item.id}" class="deleteImages1">删除</a>
- </a>
- </div>
- </div>
- </div>
- </div>
-
- <div class="row">
- <div class="col-sm-12">
- <div class="ibox float-e-margins">
- <div class="ibox-title">
- <h3>房源首页图片</h3>
- <a class="btn btn-xs btn-primary" id="upload3">上传首页默认图片</a>
- </div>
- <div class="ibox-content">
- <a th:each="item,it : ${houseImage3List}" class="fancybox" >
- <img alt="image" th:src="${item.imageUrl}"/>
- <a th:attr="data-id=${item.id}" class="deleteImages2">删除</a>
- </a>
- </div>
- </div>
- </div>
- </div>
- package com.atguigu.controller;
-
- import com.alibaba.dubbo.config.annotation.Reference;
- import com.atguigu.entity.HouseImage;
- import com.atguigu.result.Result;
- import com.atguigu.service.HouseImageService;
- import com.atguigu.util.QiniuUtils;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.multipart.MultipartFile;
-
- import java.util.Map;
- import java.util.UUID;
-
- /**
- * @Date 2022/6/22 14:12
- * @Author by:Plisetsky
- */
- @Controller
- @RequestMapping("/houseImage")
- public class HouseImageController {
-
- private static final String PAGE_UPLOAD_SHOW = "house/upload";
- private static final String ACTION_LIST = "redirect:/house/detail/";
-
- @Reference
- HouseImageService houseImageService;
-
-
- //删除默认展示图片
- @RequestMapping("/deleteDefault/{houseId}/{id}")
- public String deleteDefault(@PathVariable("houseId")Long houseId,@PathVariable("id") Long id) {
- HouseImage houseImage = houseImageService.getById(id);
- String imageName = houseImage.getImageName();
- houseImageService.delete(id);//删除前查询数据,否则删除后查不到了
- //删除house默认图片
- houseImageService.updateDefaultImage(houseId,null);
-
- //删除七牛云内图片
- QiniuUtils.deleteFileFromQiniu(imageName);
-
- return ACTION_LIST + houseId;
- }
-
- //删除房源、房产图片
- @RequestMapping("/delete/{houseId}/{id}")
- public String delete(@PathVariable("houseId")Long houseId,@PathVariable("id") Long id){
-
- HouseImage houseImage = houseImageService.getById(id);
- String imageName = houseImage.getImageName();
- houseImageService.delete(id);//删除前查询数据,否则删除后查不到了
- //删除七牛云内图片
- QiniuUtils.deleteFileFromQiniu(imageName);
-
- return ACTION_LIST + houseId;
- }
-
- //上传房源、房产图片,可以不返回值
- @RequestMapping("/upload/{houseId}/{type}")
- @ResponseBody
- public Result upload(@RequestParam("file") MultipartFile[] files, //file是固定的,底层会自动生成表单项.[]接收多个表单项
- @PathVariable("houseId") Long houseId,
- @PathVariable("type") Integer type) throws Exception { //接收上传文件,再上传到七牛云上
-
- if(files !=null && files.length>0){ //至少上传一个文件
- for (MultipartFile file:files){
- byte[] bytes = file.getBytes();
-
- //String name = file.getOriginalFilename();//原始文件名称
- //QiniuUtils.upload2Qiniu(bytes,name); 不能使用原始文件名称上传,会重名覆盖
-
- String newFileName = UUID.randomUUID().toString();
- //将图片上传到七牛云
- QiniuUtils.upload2Qiniu(bytes,newFileName);
- String imageUrl = "http://rdv0p81lw.hn-bkt.clouddn.com/"+newFileName;
-
- //如果上传的是首页默认图片,将地址更新到house表
- if(type==3){
- houseImageService.updateDefaultImage(houseId,imageUrl);
- }
-
- //将图片路径信息等保存到数据库
- HouseImage houseImage = new HouseImage();
- houseImage.setHouseId(houseId);
- houseImage.setImageName(newFileName);
- houseImage.setImageUrl(imageUrl);
- houseImage.setType(type);
- houseImageService.insert(houseImage);
- }
-
- }
- return Result.ok();
- }
- //前往上传页面
- @RequestMapping("/uploadShow/{houseId}/{type}")
- public String uploadShow(@PathVariable("houseId") Long houseId,
- @PathVariable("type") Integer type, Map map){
-
- map.put("houseId",houseId);
- map.put("type",type);
- return PAGE_UPLOAD_SHOW;
- }
- }
注意:修改webuploader-demp.js 中路径地址变量
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
- <head th:include="common/head :: head"></head>
- <!--百度上传组件-->
- <link rel="stylesheet" type="text/css" th:href="@{/static/css/plugins/webuploader/webuploader.css}">
- <link rel="stylesheet" type="text/css" th:href="@{/static/css/demo/webuploader-demo.css}">
- <script th:src="@{/static/js/plugins/webuploader/webuploader.min.js}"></script>
- <script th:src="@{/static/js/demo/webuploader-demo.js}"></script>
-
- <script type="text/javascript">
- // 添加全局站点信息 swf文件路径
- var BASE_URL = '/static/js/plugins/webuploader';
- // 自定义请求地址,传入房子id和类型
- var BASE_UPLOAD = '/houseImage/upload/[[${houseId}]]/[[${type}]]';
- // 会自动生成表单
- </script>
- <body class="gray-bg">
- <div class="row">
- <div class="col-sm-9">
- <div class="wrapper wrapper-content animated fadeInUp">
- <div class="ibox">
- <div class="ibox-content">
- <div class="row">
- <div class="ibox-content">
- <div class="page-container" id="uploadShow">
- <p>您可以尝试文件拖拽,使用QQ截屏工具,然后激活窗口后粘贴,或者点击添加图片按钮,来体验此demo.</p>
- <div id="uploader" class="wu-example">
- <div class="queueList">
- <div id="dndArea" class="placeholder">
- <div id="filePicker"></div>
- <p>或将照片拖到这里,单次最多可选300张</p>
- </div>
- </div>
- <div class="statusBar" style="display:none;">
- <div class="progress">
- <span class="text">0%</span>
- <span class="percentage"></span>
- </div>
- <div class="info"></div>
- <div class="btns">
- <div id="filePicker2"></div>
- <div class="uploadBtn">开始上传</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-4 col-sm-offset-2">
- <button class="btn btn-primary" type="button" onclick="opt.closeWin(true);">确定</button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- </html>
6 上传测试
<a class="upload" th:attr="data-id=${item.id}">上传头像</a>
- $(".upload").on("click",function(){
- var id = $(this).attr("data-id");
- opt.openWin('/admin/uploadShow/'+id,'上传头像',580,300);
- });
- //头像上传
- @RequestMapping("/upload/{id}")
- public String upload(@PathVariable("id") Long id,
- @PathVariable("file") MultipartFile file,HttpServletRequest request) throws IOException {
- //1.上传到七牛云
- byte[] bytes = file.getBytes();
- String newFileName = UUID.randomUUID().toString();
- QiniuUtils.upload2Qiniu(bytes,newFileName);
-
- //2.地址存储到数据库
- String imageUrl = "你的七牛云空间的域名/"+newFileName;
- Admin admin = new Admin();
- admin.setId(id);
- admin.setHeadUrl(imageUrl);
- adminService.update(admin);
-
- return this.successPage(this.MESSAGE_SUCCESS, request);
- }
-
-
- //前往头像上传
- @RequestMapping("/uploadShow/{id}")
- public String uploadShow(@PathVariable("id") Long id,Map map){
- map.put("id",id);
-
- return PAGE_UPLOAD;
- }
admin/upload.html
- <!DOCTYPE html>
- <html xmlns:th="http://www.thymeleaf.org">
- <head th:include="common/head :: head"></head>
- <body class="gray-bg">
- <div class="wrapper wrapper-content animated fadeInRight">
- <div class="ibox float-e-margins">
- <div class="ibox-content" style="width: 98%;">
- <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>
- </form>
- </div>
- </div>
- </div>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。