成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

太方便了!SpringBoot 只需一個注解,就能搞定任意對象下載!

開發 前端
?在日常開發中,文件下載是一個常見的功能,雖然在項目中出現的頻率可能不算太高,但幾乎每個項目都會涉及。而有些下載需求相對復雜,雖然不是難點,但實現起來卻十分繁瑣。

在日常開發中,文件下載是一個常見的功能,雖然在項目中出現的頻率可能不算太高,但幾乎每個項目都會涉及。而有些下載需求相對復雜,雖然不是難點,但實現起來卻十分繁瑣。

因此,為了簡化這一過程,有一個工具庫,使得下載功能的實現變得更加簡單快捷。

https://github.com/Linyuzai/concept/wiki/Concept-Download

一鍵下載任意對象

如果告訴你,現在僅需一個注解就能輕松下載任意對象,你會不會覺得很方便?

import com.icoderoad.download.annotation.Download;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;


@RestController
public class DownloadController {


    @Download(source = "classpath:/download/README.txt")
    @GetMapping("/classpath")
    public void downloadFromClasspath() {
    }


    @Download
    @GetMapping("/file")
    public File downloadFile() {
        return new File("/Users/Shared/README.txt");
    }


    @Download
    @GetMapping("/http")
    public String downloadFromHttp() {
        return "http://127.0.0.1:8080/icoderoad-download/image.jpg";
    }
}

看起來似乎沒有太大變化?那讓我們看看一個實際場景。

真實業務中的應用

在一個設備管理平臺中,每個設備都會有一個二維碼圖片,其地址存儲在數據庫的一個字段中。現需導出所有設備的二維碼圖片,并以設備名稱命名,最終打包成 ZIP 文件。

實現這一需求,需要:

  1. 查詢設備列表。
  2. 根據二維碼 URL 下載圖片并存入本地緩存。
  3. 處理緩存判斷,避免重復下載。
  4. 并發下載以提升性能。
  5. 下載完成后生成 ZIP 文件。
  6. 將 ZIP 文件寫入響應流。

整個實現過程大約需要 200 行代碼,顯得十分冗長繁瑣。于是我思考是否有更簡單的方法。

其實,我們只需要提供待下載的數據,比如文件路徑、文件對象、文本內容、HTTP 地址,甚至是一個自定義對象,而無需關注下載邏輯。

于是,我們可以這樣簡化實現:

import com.icoderoad.download.annotation.Download;
import com.icoderoad.download.annotation.SourceName;
import com.icoderoad.download.annotation.SourceObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;


@RestController
public class DeviceDownloadController {


    private final DeviceService deviceService;


    public DeviceDownloadController(DeviceService deviceService) {
        this.deviceService = deviceService;
    }


    @Download(filename = "二維碼.zip")
    @GetMapping("/download")
    public List<Device> downloadDevices() {
        return deviceService.all();
    }
}


class Device {
    private String name;


    @SourceObject
    private String qrCodeUrl;


    @SourceName
    public String getQrCodeName() {
        return name + ".png";
    }
}

只需標注注解,系統會自動處理文件名稱、下載內容、打包等邏輯,無需手動編寫大量代碼。

設計思路

這一功能的核心思想是基于 AOP 攔截下載請求,并結合 Spring WebFlux 進行異步處理。

@Download 注解說明

參數

說明

source

需要下載的內容,但是優先級低于返回值 如果方法返回值不為null則會使用返回值作為下載的內容

inline

如果為true,可以直接在瀏覽器預覽 需要配合contentType,如圖片或視頻,默認false 視頻文件目前存在一些問題,還在測試階段

filename

指定下載時瀏覽器上顯示的名稱 如果不指定則會獲取下載內容的名稱,如文件則使用文件名

contentType

如果未指定,會嘗試獲取 如果嘗試獲取失敗,則默認application/octet-stream 或application/x-zip-compressed

compressFormat

壓縮格式,默認zip

forceCompress

強制壓縮 如果為true,不管下載的文件有幾個都會壓縮 如果為false,有多個文件時壓縮,只有一個文件時不壓縮 默認false

charset

如果下載包含中文的文本文件出現亂碼,可以嘗試指定編碼

headers

統一的響應頭,每2個為一組

extra

額外的數據,當需要自行編寫額外流程業務時可能會用到

整體流程

圖片圖片

響應式支持

為了兼容 Spring WebFlux,我們需要獲取 ServerHttpResponse,但不能直接使用 RequestContextHolder,因此可以通過 WebFilter 進行注入:

import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;


public class ReactiveDownloadFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return chain.filter(exchange)
                .contextWrite(ctx -> ctx.put(ServerHttpResponse.class, exchange.getResponse()));
    }
}

然后在需要的地方通過 ReactiveDownloadHolder 獲取響應對象。

import org.springframework.web.server.ServerHttpResponse;
import reactor.core.publisher.Mono;


public class ReactiveDownloadHolder {
    public static Mono<ServerHttpResponse> getResponse() {
        return Mono.deferContextual(ctx -> Mono.just(ctx.get(ServerHttpResponse.class)));
    }
}

處理下載任務

下載任務分為多個步驟,例如:

  1. 獲取文件路徑或 File 對象。
  2. 如果是多個文件,則先進行壓縮處理。
  3. 將最終文件寫入響應流。

因此,我們采用類似 Spring Cloud Gateway 過濾鏈的方式,設計了 DownloadHandler:

import reactor.core.publisher.Mono;

public interface DownloadHandler {
    Mono<Void> handle(DownloadContext context, DownloadHandlerChain chain);
}

每個 DownloadHandler 處理特定任務,如下載、壓縮、寫入響應流等。

適配多種數據源

不同類型的下載對象需要不同的處理方式,例如文件、HTTP 地址、自定義對象等,因此我們抽象出 Source 接口,并通過 SourceFactory 進行匹配。

public interface SourceFactory {
    boolean support(Object source, DownloadContext context);
    Source create(Object source, DownloadContext context);
}

例如:

public class FileSourceFactory implements SourceFactory {
    @Override
    public boolean support(Object source, DownloadContext context) {
        return source instanceof File;
    }


    @Override
    public Source create(Object source, DownloadContext context) {
        return new FileSource((File) source);
    }
}

結語

這個工具庫極大簡化了文件下載功能,尤其是針對復雜的批量下載需求,只需簡單的注解即可完成。如果你正在開發 SpringBoot 3.4 版本的項目,并需要實現高效的下載功能,不妨試試這個方案!

責任編輯:武曉燕 來源: 路條編程
相關推薦

2022-09-14 10:16:12

MyBatis加密解密

2024-09-27 15:24:15

Spring數據加解密

2024-10-17 11:09:46

2022-05-26 10:42:30

數據權限注解

2022-07-15 14:26:36

開源工具IP

2022-06-14 10:47:27

項目日志PUT

2021-10-19 18:22:50

Map 注冊表源碼

2021-09-24 15:00:26

微信PC電腦移動應用

2022-06-27 08:36:27

分布式事務XA規范

2024-02-19 00:21:45

開源圖片

2021-11-23 23:01:40

Windows微軟系統

2021-09-24 09:59:59

復制粘貼PythonPDF

2025-07-02 07:35:29

JSON字段SpringBoot

2019-07-24 10:50:56

Python 開發編程語言

2021-02-08 11:46:17

Python自動化郵件

2024-04-15 00:00:02

OpenAI模型性能

2020-01-07 11:30:50

圖像識別AI人工智能

2021-10-22 22:38:01

手機系統技術

2021-10-25 22:50:04

手機系統設置

2025-04-08 01:00:00

Spring開發系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲成人一区二区三区 | 国产精品1区 | 成人啊啊啊 | 有码一区| eeuss国产一区二区三区四区 | 亚洲精品成人 | 91九色在线观看 | 青青草综合 | 免费在线黄 | 国产精品一区在线观看你懂的 | 久久网一区二区三区 | 在线观看国产视频 | 伊人免费观看视频 | 日韩欧美视频 | 成人国产免费视频 | 亚洲成av | 天天激情综合 | 久久tv在线观看 | 日韩精品免费 | 一区二区视频 | 精品国产成人 | 三级黄色片在线播放 | 喷水毛片| 国产精品一区二区久久 | 国产999精品久久久久久 | 欧美精品第一页 | 成人欧美一区二区三区视频xxx | 欧美精品99 | 国产精品视频一区二区三区 | 欧美国产激情二区三区 | 在线看一区二区 | 激情福利视频 | 日韩h| 秋霞电影一区二区三区 | 免费一级大片 | 午夜精品久久久久久久星辰影院 | 国产精品揄拍一区二区久久国内亚洲精 | 性色的免费视频 | 免费在线观看av | 337p日本欧洲亚洲大胆鲁鲁 | 伦理二区|