Day88.七牛云: 房源图片、用户头像上传 Common-upload、Webuploader

目录

一、七牛云存储

4.鉴权

 二、开发者中心,上传、删除测试

1.添加依赖

2.代码测试 

3. 封装工具类

三、房源图片上传

1. spring mvc 配置上传支持

2. house/show.html页面添加事件

3.添加服务器端代码

4. 上传页面

四、用户头像上传

1、用户列表页添加选项

2、添加服务器端代码

3、上传页面


在实际开发中,我们会有很多处理不同功能的服务器。例如:

应用服务器:负责部署我们的应用

数据库服务器:运行我们的数据库

文件服务器:负责存储用户上传文件的服务器

分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。

常见的图片存储方案:

方案一:使用nginx搭建图片服务器

方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等

方案三:使用云存储,例如阿里云、==七牛云==等

一、七牛云存储

七牛云(隶属于上海七牛信息技术有限公司)是国内领先的以视觉智能和数据智能为核心的企业级云计算服务商,同时也是国内知名智能视频云服务商,累计为 70 多万家企业提供服务,覆盖了国内80%网民。围绕富媒体场景推出了对象存储、融合 CDN 加速、容器云、大数据平台、深度学习平台等产品、并提供一站式智能视频云解决方案。为各行业及应用提供可持续发展的智能视频云生态,帮助企业快速上云,创造更广阔的商业价值。

官网:七牛云 - 国内领先的企业级云服务商

1.注册、登录

要使用七牛云的服务,首先需要注册成为会员。地址:七牛云开发者平台

2.新建存储空间

 3.查看存储空间信息

4.鉴权

Java SDK的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对==有效的Access Key和Secret Key==,这对密钥可以在七牛云管理控制台的个人中心(七牛云开发者平台)获得,如下图:

 二、开发者中心,上传、删除测试

可以通过七牛云提供的开发者中心学习如何操作七牛云服务,代码测试

地址:七牛开发者中心

1.添加依赖

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>

2.代码测试 

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());
        }
    }
}

3. 封装工具类

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());
        }
    }
}

三、房源图片上传

1. 需要添加依赖 Common-upload组件

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>

2. spring mvc 配置上传支持 文件上传解析器

在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>

3. house/show.html页面添加事件

    $(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>

4.添加服务器端代码

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;
    }
}

5. 上传页面 (webuploader上传组件)

注意:修改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 上传测试

四、用户头像上传

1、用户列表页添加选项

<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);
});

2、添加服务器端代码

    //头像上传
    @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;
    }

3、上传页面

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>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
el-upload是一个用于上图片的组件,而七牛云是一种云存储服务。你可以通过将这两者结合使用,实现将图片到七牛云的功能。 具体的步骤如下: 1. 首先,你需要从后台获取七牛云的token,这个token将用于上图片到七牛云。你可以通过调用后端提供的接口,入AccessKey、SecretKey和Bucket等信息来获取token。 2. 在el-upload组件中,你需要配置action属性为https://upload.qiniup.com,这是七牛云存储区域的上地址。不同的七牛云存储区域可能会有不同的地址,请根据自己使用的七牛云服务器存储区域来确定具体的地址。 3. 配置el-upload组件的其他参数,如class、list-type、file-list等。这些参数可以根据自己的需求进行设置。 4. 在el-upload组件中,你可以监听onChange事件,以便在图片完成后执行相应的操作。比如,你可以在该事件中获取返回的图片路径,并将其放入el-upload组件中进行显示。 5. 当图片成功后,你可以在el-upload组件中使用on-success事件来回显上图片。你需要将回显地址配置为你在七牛云上配置的回显地址,具体地址可以参考七牛云的官方文档。 6. 最后,你可以根据需要配置其他的el-upload组件参数,如before-upload、on-remove等。 总结起来,通过el-upload组件和七牛云的配合,你可以实现在前端上图片到七牛云,并在上成功后进行回显操作。详情可以参考提供的引用内容中的代码和注意点。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue中el-upload上图片到七牛的示例代码](https://download.csdn.net/download/weixin_38675465/13977470)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [elementUI el-upload组件直接上到七牛云(亲测可用)](https://blog.csdn.net/DLGDark/article/details/126763197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [el-upload上文件到七牛云](https://blog.csdn.net/qq_42157868/article/details/107286616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值