前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我花了3块6,给自己搞了一个在线图床功能

我花了3块6,给自己搞了一个在线图床功能

原创
作者头像
不惑
修改2024-11-13 14:40:21
2412
修改2024-11-13 14:40:21
举报
文章被收录于专栏:Goboy

快来薅羊毛:轻量云对象存储

随着社交媒体和图片分享平台的广泛应用,图床(即图片托管服务)成为了开发者和内容创作者不可或缺的一部分。图床允许用户将图片上传到云端存储,并通过 URL 进行访问,减少了用户设备上的存储空间占用,同时提供了高效的图片管理和访问方式。腾讯云的轻量对象存储(COS)为开发者提供了一个简单且高效的图床解决方案,本文将介绍如何使用腾讯云 COS 构建一个完整的在线图床功能。

1. 什么是图床

图床(Image Hosting Service)是指将图片存储在云端服务器上,通过 HTTP 或 HTTPS 协议提供图片访问链接的服务。图床的核心功能包括:通过图床,用户无需再将图片存储在本地服务器上,大大提高了系统的扩展性和图片访问速度。

  • 图片上传:用户可以将图片上传到云端。
  • 图片存储:图片保存在云存储上,并根据文件名生成唯一的文件路径或 URL。
  • 图片访问:用户通过 URL 来访问已上传的图片。

2. 腾讯云轻量对象存储 COS

腾讯云 COS(Cloud Object Storage)是腾讯云提供的一种云存储服务,适合存储海量非结构化数据,如图片、视频、日志等。其具备以下特点:

  • 高可靠性:COS 提供多副本存储机制,确保数据的高可用性和持久性。
  • 低成本:COS 提供按需计费服务,用户只需为实际存储和流量付费,适合各种规模的应用场景。
  • 高性能:COS 提供快速的数据访问能力,特别适合图片和视频等大数据量的存储和访问。
  • 易于集成:腾讯云提供丰富的 SDK 和 API,使得 COS 可以方便地与现有应用程序集成。

3. 构建图床的需求

一个完整的在线图床功能需要满足以下需求:在实现这些需求之前,我们需要进行一些基本的准备工作。

  1. 用户注册与认证:用户需要进行身份验证,以确保图片上传和管理是私密的。
  2. 图片上传:支持上传单张或多张图片,且上传的图片可以按需生成 URL 地址。
  3. 图片存储:上传的图片会存储在腾讯云 COS 中,支持大文件存储和快速访问。
  4. 图片管理:用户可以查看已上传的图片,支持删除或更新图片。
  5. 图片访问:通过 URL 访问已上传的图片,支持前端展示。

4. 准备工作

4.1 注册腾讯云账号

首先,前往 腾讯云官网 注册一个腾讯云账号。如果已有账号,可以直接登录。

4.2 创建腾讯云 COS 存储桶

  1. 登录腾讯云管理控制台,找到 COS 服务。
  2. 创建一个新的存储桶,并设置访问权限(公共读或私有读等)。
  3. 获取 AppIDSecretIDSecretKey,这些信息将用于后续的 SDK 配置和鉴权。

4.3 配置环境

为了在 Java 项目中使用腾讯云 COS,需要导入腾讯云的 SDK。以下是添加依赖的方式。

使用 Maven 管理依赖

pom.xml 文件中加入以下依赖:

代码语言:xml
复制
		<dependency>
			<groupId>com.qcloud</groupId>
			<artifactId>cos_api</artifactId>
			<version>5.6.54</version>
		</dependency>
配置腾讯云 COS 参数

application.propertiesapplication.yml 中配置腾讯云 COS 相关参数:

代码语言:properties
复制
tencent:
  cos:
    secretId: xxxxxxx
    secretKey: xxxxxxxxxxxxxxxxx
    region: ap-nanjing
    bucketName: number-89757-1259242531

5. 后端实现

5.1 创建实体类

首先,我们需要创建一个实体类 Image 来存储图床中的图片信息,包括图片的 URL、文件名、文件大小等。

代码语言:java
复制
package com.example.demo.entity;

// 响应 DTO
public  class ResponseDto {
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

5.3 创建 COS 服务

接下来,我们创建一个 CosService 类来封装所有与腾讯云 COS 相关的操作,包括上传、删除、获取文件等功能。

代码语言:java
复制
package com.example.demo.service;

import com.example.demo.controller.CosImageController;
import com.example.demo.entity.ResponseDto;
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.region.Region;
import com.qcloud.cos.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Service
public class CosService {

    @Value("${tencent.cos.secretId}")
    private String secretId;

    @Value("${tencent.cos.secretKey}")
    private String secretKey;

    @Value("${tencent.cos.region}")
    private String region;

    @Value("${tencent.cos.bucketName}")
    private String bucketName;

    /**
     * 上传文件到 COS
     *
     * @param file    上传的文件
     * @param key     上传到 COS 的对象键
     * @return        文件的 URL 地址
     * @throws IOException
     */
    public String uploadFile(File file, String key) throws IOException {

        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        COSClient cosClient = new COSClient(cred, clientConfig);
//        // 创建上传请求
//        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
//        // 执行上传
//        cosClient.putObject(putObjectRequest);
        FileInputStream fileInputStream = new FileInputStream(file);
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, fileInputStream, new ObjectMetadata());
        cosClient.putObject(putObjectRequest);

        // 生成文件的 URL 地址
        return "https://" + bucketName + ".cos." + region + ".myqcloud.com/" + key;
    }

    /**
     * 删除 COS 中的文件
     *
     * @param key 文件的对象键
     */
    public void deleteFile(String key) {

        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        COSClient cosClient = new COSClient(cred, clientConfig);
        cosClient.deleteObject(bucketName, key);
    }

    /**
     * 获取 COS 中所有文件的列表
     *
     * @return 文件列表
     */
    public List<ResponseDto> listFiles() {
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        COSClient cosClient = new COSClient(cred, clientConfig);
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
                .withBucketName(bucketName)
                .withPrefix("");  // 可以设置前缀来过滤文件
        ObjectListing objectListing = cosClient.listObjects(listObjectsRequest);
        List<COSObjectSummary> aa = objectListing.getObjectSummaries();
        List<ResponseDto> result = new ArrayList<>();
        for (COSObjectSummary vv :aa){
            ResponseDto dd = new ResponseDto();
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, vv.getKey());
//        req.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)); // 设置URL有效期为1小时
            URL signedUrl = cosClient.generatePresignedUrl(req);
            dd.setUrl(signedUrl.toString());
            result.add(dd);
        }
        return result;
    }

    /**
     * 转换 MultipartFile 为 File 对象
     *
     * @param file 上传的 MultipartFile 文件
     * @return     转换后的 File 对象
     * @throws IOException
     */
    public File convertMultiPartToFile(MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        file.transferTo(convFile);
        return convFile;
    }

    /**
     * 关闭 COS 客户端
     */
    public void shutdown() {
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        COSClient cosClient = new COSClient(cred, clientConfig);
        cosClient.shutdown();
    }
}

5.4 创建控制器

控制器 ImageController 处理前端的请求,例如上传图片、列出图片、删除图片等。

代码语言:java
复制
package com.example.demo.controller;

import com.example.demo.entity.ResponseDto;
import com.example.demo.service.CosService;
import com.qcloud.cos.model.COSObjectSummary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.ResponseEntity;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;

@Controller
public class CosImageController {

    @Autowired
    private CosService cosService;  // 调用 COS 服务

    // 图片存储路径
    private static final String UPLOAD_DIR = "src/main/resources/static/uploads/";

    @GetMapping("/")
    public String ocrPage() {
        return "cos"; // 返回上传页面视图
    }
    // 上传图片
    @PostMapping("/image/upload")
    public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
        // 将上传的文件保存到 COS

        // 确保上传目录存在
        Path uploadPath = Paths.get(UPLOAD_DIR);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }

        // 获取文件输入流并存储文件
        Path filePath = uploadPath.resolve(file.getOriginalFilename());
        try (InputStream inputStream = file.getInputStream()) {
            Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
        }

        try {
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
//            String fileUrl = cosService.uploadFile(convertMultiPartToFile(file), fileName);
            String fileUrl = cosService.uploadFile(filePath.toFile(), fileName);
            System.out.printf(fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:/";
    }

    // 获取已上传的图片列表
    @GetMapping("/image/list")
    @ResponseBody
    public List<ResponseDto> getImageList() {
        // 这里假设已经存储了图片的 URL 和 ID
        List<ResponseDto> sss = cosService.listFiles();
        return sss;  // 你可以从数据库或 COS 获取图片信息
    }

    // 删除图片
    @DeleteMapping("/image/delete/{id}")
    public ResponseEntity<?> deleteImage(@PathVariable String id) {
        // 根据 ID 删除文件
        cosService.deleteFile(id);  // 你可以根据文件 ID 从 COS 删除文件
        return ResponseEntity.ok().build();
    }

    // 辅助方法:转换 MultipartFile 为 File
    private File convertMultiPartToFile(MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        file.transferTo(convFile);
        return convFile;
    }



    // 图片信息 DTO
    public static class ImageDto {
        private String id;
        private String url;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }
}

6. 前端实现

前端部分实现图床的用户界面,支持图片上传和展示。

代码语言:html
复制
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图床管理</title>
    <!-- 引入 Bootstrap 样式 -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .image-preview {
            max-width: 100px;
            max-height: 100px;
            object-fit: cover;
        }
    </style>
</head>
<body>

<div class="container mt-5">
    <h1 class="mb-4">图床管理</h1>

    <!-- 图片上传部分 -->
    <div class="mb-4">
        <h3>上传图片</h3>
        <form action="/image/upload" method="post" enctype="multipart/form-data">
            <input type="file" class="form-control" name="file" required>
            <button type="submit" class="btn btn-primary">上传</button>
        </form>
    </div>

    <!-- 已上传的图片列表 -->
    <h3>已上传图片</h3>
    <div id="imageList" class="row"></div>
</div>

<!-- 引入 jQuery 和 Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>

        // 加载已上传的图片列表
        function loadImageList() {
            $.ajax({
                url: '/image/list',  // 后端获取图片列表的接口
                type: 'GET',
                success: function (images) {
                    $('#imageList').empty();  // 清空当前列表
                    images.forEach(function (image) {
                        $('#imageList').append(`
                            <div class="col-md-3 mb-3">
                                <div class="card">
                                    <img src="${image.url}" class="card-img-top" alt="Image" style="height: 150px; object-fit: cover;">
                                    <div class="card-body">
                                        <a href="${image.url}" target="_blank" class="btn btn-primary btn-sm">查看</a>
                                        <button class="btn btn-danger btn-sm delete-btn" data-id="${image.id}">删除</button>
                                    </div>
                                </div>
                            </div>
                        `);
                    });
                },
                error: function (xhr, status, error) {
                    alert("加载图片列表失败:" + error);
                }
            });
        }

        // 删除图片
        $(document).on('click', '.delete-btn', function () {
            var imageId = $(this).data('id');
            $.ajax({
                url: '/image/delete/' + imageId,  // 后端删除图片的接口
                type: 'DELETE',
                success: function () {
                    loadImageList();  // 更新图片列表
                },
                error: function (xhr, status, error) {
                    alert("删除失败:" + error);
                }
            });
        });

        // 初始化时加载图片列表
        loadImageList();
</script>

</body>
</html>

7. 效果展示

我们使用了 Spring Boot 构建后端,腾讯云 COS 作为存储服务,并实现了图片上传、删除和展示等功能。通过前端 HTML 页面,我们实现了图片上传和查看功能。通过这种方式,我们不仅可以实现一个高效、可靠的图床系统,还能够充分利用腾讯云的云存储优势,提高系统的性能和可扩展性。

8. 使用COS减轻轻量应用服务器功能压力

当然,在实际的项目开发过程中,我们也可以使用腾讯云对象存储有效减轻轻量应用服务器的功能压力,提升应用性能和稳定性。COS提供了高可靠性、高可用性和低成本的数据存储解决方案,适用于各种规模的应用场景。

  1. 创建存储桶:在腾讯云控制台上创建一个存储桶,用于存储对象数据。
  2. 上传对象:将文件或数据上传到COS存储桶中,支持多种上传方式。
  3. 访问对象:通过生成的URL链接访问存储桶中的对象数据,支持公有访问和私有访问。
  4. 挂载存储桶:在轻量应用服务器上挂载COS存储桶,以便在应用程序中读取和写入数据。

就是现在兄弟们,轻量应用服务器*限时秒杀,一年仅需28!!!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是图床
  • 2. 腾讯云轻量对象存储 COS
  • 3. 构建图床的需求
  • 4. 准备工作
    • 4.1 注册腾讯云账号
      • 4.2 创建腾讯云 COS 存储桶
        • 4.3 配置环境
          • 使用 Maven 管理依赖
          • 配置腾讯云 COS 参数
      • 5. 后端实现
        • 5.1 创建实体类
          • 5.3 创建 COS 服务
            • 5.4 创建控制器
            • 6. 前端实现
            • 7. 效果展示
            • 8. 使用COS减轻轻量应用服务器功能压力
            相关产品与服务
            对象存储
            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档