10 分钟使用 Spring Boot + Vue + Antd + US3 搭建自己的图床

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 10 分钟使用 Spring Boot + Vue + Antd + US3 搭建自己的图床

点击上方 **好好学java **,选择 **星标 **公众号

重磅资讯、干货,第一时间送达

今日推荐:

 个人原创100W+访问量博客:点击前往,查看更多

网上已经一些运行不错的图床了,比如

  1. SM.MS https://sm.ms/1. 图壳 https://imgkr.com1. 路过图床 https://imgchr.com/
    那为什么我们还要自己搭建图床呢?一来是因为码农总是喜欢折腾,二来是有了自己的图床数据自己存储更安全。那么接下来我们就搞起来。下面是演示地址,可以先看一下搭建完成的效果。

https://xiaotuwo.github.io点击按钮上传图片,完成以后可以复制链接和下载

准备前端环境

  1. 安装 nodejs自行去nodejs 官网下载,我们主要是为了使用 npm 工具。1. 安装淘宝镜像,如果是在国内,下载镜像很慢,所以使用国内的镜像   。
    ```
    sudo npm install -g cnpm –registry=https://registry.npm.taobao.org

1. 安装 vue-cli 工具因为我们前端使用的 vue,所以需要安装vue-cli

cnpm install -g @vue/cli


1. 创建项目

vue create xiaotuwo


1. 添加 antd 依赖

cnpm install ant-design-vue –save


1. 启动

cd xiaotuwo  
npm run serve  


1. 访问,能够访问 HelloWorld 页面说明我们环境准备成功了。

http://localhost:8080



## 编写前端代码 

到这里我们基础环境就搭建完成了,下面就开始编写前端的代码。我们是以 sm.ms 作为原型进行搭建。如下图我们只编辑他的头部,上传部分和尾部

成品形态如下,把 sm.ms 拖拽上传图片的交互设计改成了点击上传图片,不过如果你想实现拖拽也是非常简单,下面是 antd 的样式,换一个标签即可。https://www.antdv.com/components/upload-cn/

头部和尾部代码非常简单,我们只讲解上传部分代码。搭建好 vue 框架以后去上面提供的 antd 的网址里面找到 upload 控件,直接点击复制自己喜欢的代码样式,粘贴到 `content/index.vue` 里面就可以了,然后修改 `a-upload` 的 action 为自己的服务器地址即可,本地测试就是`http://localhost:8887/api/images/upload`,下文中也有配套的服务端代码。

vue 的语法就不具体展开了,主要讲解一个地方, `handlePreview` 方法里面我添加了一个复制链接的逻辑,可以轻松的点击预览的时候复制图片链接,这样方便的把网址放入其他地方进行使用。

his.$message.success(‘复制图片链接成功’);
document.addEventListener(“copy”, function copyCall(e) {
  e.preventDefault()
  e.clipboardData.setData(“text/html”, file.preview)
  e.clipboardData.setData(“text/plain”, file.preview)
  document.removeEventListener(“copy”, copyCall)
})



到这里基本的前端的搭建完成了,可以直接查看源码https://github.com/xiaotuwo/xiaotuwo-client

## 服务器端环境准备 

本文采用的是 US3 进行图床搭建,目前 US3 有 20G 的免费存储和 每个月 20G 的免费流量,对于自用和起步还是足够的。

复制下面的链接到浏览器访问查看 US3 官网,首次进入需要注册https://urlify.cn/YNNBNn注册完成以后,进入控制台创建 US3 空间

进入空间以后填写存储名,私有空间和公开空间都可以,我创建的是 `xiaotuwo.cn-bj.ufileos.com` 留存备用。<img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy83QjhpYWF1QWZjbE93c3VmSmRtYzlLSzZqZ293VVJFUXVDTnpIaEUzZkZXbURtT3BtblhCaWJVMFZ4WVRjRUJGUlBXMHB1QjNKaWJSVVIxOGp4MHFOZGdxQS82NDA?x-oss-process=image/format,png">

在 US3 控制台创建令牌,主要是用来上传,删除图片使用

选择好自己刚才创建的空间,设置年限点击确定即可,记得一定要勾选令牌的权限

<img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy83QjhpYWF1QWZjbE93c3VmSmRtYzlLSzZqZ293VVJFUXVmdm5FaWFOY1dMM2t0eWRvR2hXUUR4UjlWYk9UNWRvaDd5MGR3OERzbmNOMHVVbnIwbUt0SnRRLzY0MA?x-oss-process=image/format,png">点击完成以后获取到公钥私钥,复制备用

## 编写服务端代码 

服务端代码主要分为三个部分1、接收请求的 Controller2、上传图片到 US3 的逻辑3、返回内容处理

1、 编写 Controller使用 `MultipartHttpServletRequest` 接收到前端的 file 文件,调用 `uCloudProvider` 进行上传。

@PostMapping({“/api/files/upload”})
    @ResponseBody
    public FileDTO upload(HttpServletRequest request) {
        FileDTO resultFileDTO = new FileDTO();
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile(“file”);
        long start = System.currentTimeMillis();
        try {
            if (file == null) {
                resultFileDTO.setStatus(“error”);
            }
            FileDTO fileDTO = uCloudProvider.uploadWithExpired(file.getInputStream(), file.getContentType(), Objects.requireNonNull(file.getOriginalFilename()));
            log.info(“UPLOAD_FILE_EXPIRED|ip:{}|referer:{}|url:{}|cost:{}”, getIpAddress(request), request.getHeader(“referer”), fileDTO.getUrl(), System.currentTimeMillis() - start);
            executorService.submit(new UCloudScanner(fileDTO, uCloudProvider, executorService, 1));
            resultFileDTO.setName(fileDTO.getName());
            resultFileDTO.setUrl(fileDTO.getUrl());
            resultFileDTO.setThumbUrl(fileDTO.getUrl());
            resultFileDTO.setStatus(“done”);
        } catch (Exception e) {
            log.error(“UPLOAD_FILE_ERROR”, e);
            resultFileDTO.setStatus(“error”);
        }
        return resultFileDTO;
    }



2、上传图片到 US3 的逻辑上传 US3 主要是一些配置文件,我直接使用的 Maven 的 Filter 处理,配置文件在 pom.xml 里面,编译的时候写入 application.properties

<id>dev</id>
<properties>
    <server.port>8887</server.port>
    <ucloud.ufile.public-key>你的公钥</ucloud.ufile.public-key>
    <ucloud.ufile.private-key>你的私钥</ucloud.ufile.private-key>
    <ucloud.ufile.upload-domain-private>你的bucket名字.cn-bj.ufileos.com</ucloud.ufile.upload-domain-private>
    <ucloud.ufile.download-domain-private>你的bucket名字.cn-bj.ufileos.com</ucloud.ufile.download-domain-private>
    <ucloud.uaicensor.publicKey>鉴黄公钥</ucloud.uaicensor.publicKey>
    <ucloud.uaicensor.privateKey>鉴黄私钥</ucloud.uaicensor.privateKey>
    <ucloud.uaicensor.resourceId>鉴黄ID</ucloud.uaicensor.resourceId>
    <ucloud.uaicensor.url>http://api.uai.ucloud.cn/v1/image/scan</ucloud.uaicensor.url>
</properties>
<activation>
    <activeByDefault>true</activeByDefault>
</activation>



我们会发现配置文件里面除了文件的配置还有一套鉴黄的配置,对的这个地方不是本文的重点,但是图床一定要有鉴黄的能力,具体的实现可以参考文章 具体 US3 的逻辑代码也是非常的简单,主要的逻辑就是上传,使用私钥和时间戳生成链接,显示。

public FileDTO upload(InputStream fileStream, String mimeType, String fileName) {
        String generatedFileName;
        String[] filePaths = fileName.split(“\.”);
        if (filePaths.length > 1) {
            generatedFileName = UUID.randomUUID().toString() + “.” + filePaths[filePaths.length - 1];
        } else {
            throw new ErrorCodeException(ErrorCode.FILE_UPLOAD_FAIL);
        }
        long start = System.currentTimeMillis();
        try {
            log.debug(“UCloudProvider start upload file, filename : {}, time : {}”, fileName, new Date());
            ObjectAuthorization objectAuthorization = new UfileObjectLocalAuthorization(publicKey, privateKey);
            ObjectConfig config = new ObjectConfig(uploadDomainPrivate);
            PutObjectResultBean response = UfileClient.object(objectAuthorization, config)
                    .putObject(fileStream, mimeType)
                    .nameAs(generatedFileName)
                    .toBucket(bucketNamePrivate)
                    .setOnProgressListener((bytesWritten, contentLength) -> {
                    })
                    .execute();
            log.debug(“UCloudProvider end upload file, filename : {}, time : {}, cost : {}”, fileName, new Date(), System.currentTimeMillis() - start);
            if (response != null && response.getRetCode() == 0) {
                long start2 = System.currentTimeMillis();
                log.debug(“UCloudProvider start get url, filename : {}, time : {}”, fileName, new Date());

                String url = UfileClient.object(objectAuthorization, new ObjectConfig(downloadDomainPrivate))
                        .getDownloadUrlFromPrivateBucket(generatedFileName, bucketNamePrivate, 24 * 60 * 60)
                        .createUrl();

                log.debug(“UCloudProvider end get url, filename : {}, time : {}, cost : {}”, fileName, new Date(), System.currentTimeMillis() - start2);

                FileDTO fileDTO = new FileDTO();
                fileDTO.setUrl(url.replace(“http”, “https”));
                fileDTO.setName(generatedFileName);
                return fileDTO;
            } else {
                log.debug(“UCloudProvider end upload file, filename : {}, time : {}, cost : {}”, fileName, new Date(), System.currentTimeMillis() - start);
                log.error(“upload error,{}”, response);
                throw new ErrorCodeException(ErrorCode.FILE_UPLOAD_FAIL);
            }
        } catch (UfileClientException | UfileServerException e) {
            log.debug(“UCloudProvider end upload file, filename : {}, time : {}, cost : {}”, fileName, new Date(), System.currentTimeMillis() - start);
            log.error(“upload error,{}”, fileName, e);
            throw new ErrorCodeException(ErrorCode.FILE_UPLOAD_FAIL);
        }
    }



3、 返回内容处理,这里也需要注意一下,为了配合 antd 的 upoad 控件,我们的 dto 如下

@Data
public class FileDTO {
    private String name;
    private String status;
    private String url;
    private String thumbUrl;
}



服务器端源码访问https://github.com/xiaotuwo/xiaotuwo-server

到这里就全部结束了,你学会了吗?如果有任何问题,可以到 US3 自己的官方论坛提问 https://uclub.ucloud.cn/invite/93

推荐文章


- - - - 

原创电子书历时整整一年总结的 Java 面试 + Java 后端技术学习指南,这是本人这几年及校招的总结,各种高频面试题已经全部进行总结,按照章节复习即可,已经拿到了大厂offer。
原创思维导图扫码或者微信搜 程序员的技术圈子 回复 面试 领取原创电子书和思维导图。

```

原文地址:https://sihai.blog.csdn.net/article/details/112255784

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 10 分钟使用 Spring Boot + Vue + Antd + US3 搭建自己的图床


 上一篇
笔记本8G+256G固态免费送,吃鸡不吃力,包邮! 笔记本8G+256G固态免费送,吃鸡不吃力,包邮!
2020已经过去,新年已至小编联系了几个好友给大家送一波礼物,回馈长期以来各位老铁对本号的关注支持。 本次直接送一款戴睿 U9s plus 15.6英寸英特尔第十代赛扬J4125笔记本电脑!不爱可折现!感谢粉丝们的鼎力支持!愿你在新的一年里
2021-04-04
下一篇 
字节,阿里, 百度2021年Java岗发布+最新内部面试题 字节,阿里, 百度2021年Java岗发布+最新内部面试题
2021刚刚启程,各互联网大厂便发布了一大波优质Java岗,平均薪资总包都在40w左右,你心动了吗?下面给大家列出几个具体的岗位及要求。 此外,在文末还有分享:由各大厂面试官整理的****字节、阿里、百度Java内部面试题(含答案),**新
2021-04-04