IDEA+springboot+thymeleaf调用腾讯云对象存储实现图片上传和调用

前言

本人小白,也开始学springboot,各位大神勿喷。因为项目需要,所以需要实现让用户在前端上传图片,保存到后端,然后在前端显示,类似个人头像这个功能。

后面查到腾讯云有个叫对象存储的东西,可以把图片存在这里面而不用放在服务器上,于是就想用对象存储来做这件事。

为实现这个功能看了不少博客,很遗憾我都忘记是哪些前辈写的了,但是我发现没有一整套的东西来说这件事,基本是分散的,所有就有了写这篇文章和的意图,也算对这阶段的一个总结。

流程

1.前端需要用JS(JQuery)来读取本地文件,并上传到后端。
2.后端调用腾讯云的对象存储,将文件存在里面
3.后端获取对象存储对应用户文件夹下的所有图片路径,因为对象存储上的图片是可以根据一个域名访问到的,可以把存储桶的访问设为公开。
4.把后端的图片路径传到前端显示。

实现

1.前端页面代码:这里主要是一个按钮,点击按钮触发事件

<div >
    
    <p>上传图片</p>

    <input style="display: none" type="file" name="file" id="file"/><br>
    <img src="" id="img" style="width: 20rem;height: 15rem;">
    <button onclick="$('#file').click()">选择</button>
    <button onclick="updateImg();">上传</button>
</div>

2.对应前端的JS代码:

var file;
//图片上传到后端的事件
function updateImg() {

    var fd = new FormData();
    fd.append("file",file);
    $.ajax({
        type: "post",
        url: "uploadImg",
        data: fd,
        processData: false,
        contentType: false,
        dataType:"text",
        //把文件传到后端
        success: function (data) {
            $("#img").attr("src",fileurl);//图片预览
            if(data){
                alert("上传成功");
                //location.reload();
            }
        },
        error: function () {
        }, xhr: function () {
            var xhr = $.ajaxSettings.xhr();
            var ot,oloaded,perload,pertime;
            xhr.upload.onload = function (){
                ot = new Date().getTime();
                oloaded=0;
            };
            xhr.upload.onprogress = function (evt) {
                var loaded = evt.loaded;
                var tot = evt.total;
                var per = Math.floor(100*loaded/tot);
            };
            return xhr;
        }, complete: function () {

        }
    })
}

//点击选择本地文件事件
$('#file').on('change', function(){

    file = document.getElementById('file').files[0];
    var fileurl = window.URL.createObjectURL(file);
    $("#img").attr("src",fileurl);

});

3.新建TencentCOS的JAVA文件:

实现将图片传到对象存储里
注:在桶里新建一个叫images的文件夹,注意修改以下代码里XXX的内容

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.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 腾讯云对象存储
 *
 */
public class TencentCOS {
	//注意修改以下XXXX的内容,该为自己的
    // 此处填写的存储桶名称
    private static final String bucketName = "XXXXX";
    // secretId
    private static final String secretId = "XXXXXX";
    // secretKey
    private static final String secretKey = "XXXXXXXXX";

    // 1 初始化用户身份信息(secretId, secretKey,可在腾讯云后台中的API密钥管理中查看!
    private static COSCredentials cred = new BasicCOSCredentials(secretId,secretKey);

    // 2 设置bucket的区域, COS地域的简称请参照
    // https://cloud.tencent.com/document/product/436/6224,根据自己创建的存储桶选择地区
    private static ClientConfig clientConfig = new ClientConfig(new Region("XXXXXXX"));


    /**
     * 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20 M 以下的文件使用该接口 大文件上传请参照 API 文档高级 API 上传
     *
     * @param localFile
     */
    public static String uploadfile(File localFile,String wechat) throws CosClientException, CosServiceException {

        // 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        String fileName = localFile.getName();
        try {
            String substring = fileName.substring(fileName.lastIndexOf("."));
            Random random = new Random();
            // 指定要上传到 COS 上的路径
            fileName = "images/"+Now.getNowTime("yyyyMMddHHmmssSSS")+substring;
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName , localFile);
            PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭客户端(关闭后台线程)
            cosclient.shutdown();
        }
        return fileName;
    }


    /**
     *
     * @Title: downFile
     * @Description: 下载文件
     * @return
     */
    public static void downFile() {
        // 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        //要下载的文件路径和名称
        String key = "/.jpg";
        // 指定文件的存储路径
        File downFile = new File("src/test/resources/mydown.txt");
        // 指定要下载的文件所在的 bucket 和对象键
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
        ObjectMetadata downObjectMeta = cosclient.getObject(getObjectRequest, downFile);
    }


    /**
     * 删除文件
     *
     * @param key
     */
    public static void deletefile(String key) throws CosClientException, CosServiceException {
        // 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // 指定要删除的 bucket 和路径
        cosclient.deleteObject(bucketName, key);
        // 关闭客户端(关闭后台线程)
        cosclient.shutdown();
    }

    //读取文件中的所有文件路径
    public static List<String> findallfile(){

        COSClient cosclient = new COSClient(cred, clientConfig);
        // Bucket的命名格式为 BucketName-APPID ,此处填写的存储桶名称必须为此格式
        String bucketName = "XXXXX";
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
// 设置bucket名称
        listObjectsRequest.setBucketName(bucketName);
// prefix表示列出的object的key以prefix开始
        listObjectsRequest.setPrefix("images/";
// deliter表示分隔符, 设置为/表示列出当前目录下的object, 设置为空表示列出所有的object
        listObjectsRequest.setDelimiter("");
// 设置最大遍历出多少个对象, 一次listobject最大支持1000
        listObjectsRequest.setMaxKeys(1000);
        ObjectListing objectListing = null;
        do {
            try {
                objectListing = cosclient.listObjects(listObjectsRequest);
            } catch (CosServiceException e) {
                e.printStackTrace();
//                return "none";
            } catch (CosClientException e) {
                e.printStackTrace();
//                return;
            }
            // common prefix表示表示被delimiter截断的路径, 如delimter设置为/, common prefix则表示所有子目录的路径
            List<String> commonPrefixs = objectListing.getCommonPrefixes();

           //定义img存储所有图片路径,返回到前端要用的
            List<String> imgs = new ArrayList<>();

            // object summary表示所有列出的object列表
            List<COSObjectSummary> cosObjectSummaries = objectListing.getObjectSummaries();
            for (COSObjectSummary cosObjectSummary : cosObjectSummaries) {
                // 文件的路径key
                String key = cosObjectSummary.getKey();
                //System.out.println(key);
                imgs.add("https://你的桶名.cos.你的地区名.myqcloud.com/"+key);
                // 文件的etag
                String etag = cosObjectSummary.getETag();

                // 文件的长度
                long fileSize = cosObjectSummary.getSize();

                // 文件的存储类型
                String storageClasses = cosObjectSummary.getStorageClass();


            }


            String nextMarker = objectListing.getNextMarker();
            listObjectsRequest.setMarker(nextMarker);
            //返回文件路径
            return imgs;
        } while (objectListing.isTruncated());
    }
}

4.新建名为:CosController控制类,将前后端绑定

import com.example.finalappointment.others.TencentCOS;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
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.util.Map;

@Controller
public class CosController {

    /**
     * 把文件上传到腾讯云存储服务器
     * @param multfile
     * @return
     * @throws Exception
     */
    @PostMapping("/uploadImg")
    @ResponseBody
    public String upload(@RequestParam("file") MultipartFile multfile, Map<String,Object> map)throws Exception{
        // 获取文件名
        
        String fileName = multfile.getOriginalFilename();
        // 获取文件后缀
        String prefix=fileName.substring(fileName.lastIndexOf("."));
        // 用uuid作为文件名,防止生成的临时文件重复
        final File excelFile = File.createTempFile("imagesFile-"+System.currentTimeMillis(), prefix);
        // 将MultipartFile转为File
        multfile.transferTo(excelFile);

        //调用腾讯云工具上传文件
        String fileName1 = TencentCOS.uploadfile(excelFile,wechat);

        //程序结束时,删除临时文件
        deleteFile(excelFile);
        //存入图片名称,用于网页显示
        map.put("imageName",fileName1);
        //返回图片名称
        return "index";
    }

    /**
     * 删除临时文件
     * @param files
     */
    private void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }
}

5.后端调用函数获取对象存储的所有文件名

//这里我要用thymeleaf的语法
 @GetMapping("前端页面名")
    public String showimg(ModelMap modelMap){

        //调用COS的函数获取所有文件路径
        List<String> imgpaths = TencentCOS.findallfile();
		//所有文件路径传到前端去
        modelMap.addAttribute("imgpaths",imgpaths );

       
        return "前端页面名";
    }

6.前端接收图片

<!doctype html>
<html lang="zh-CN" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<!--显示后台传过来的图片-->
 <div th:each="imgpath:${imgpaths}">
        <img th:src="${imgpath}" id="img1" style="width: 20rem;height: 15rem;">	
</body>
</html>
   

总结

这里只是实现上传和预览,没有针对单个用户上传进行区分,这一点根据大家的需求自己调整。
以上肯定还有很多不足之处,希望大家多多指教。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值