Backend Development 14 min read

Concept-Download: A Spring‑Based Library for Simplified File Download, Compression and Reactive Streaming

This article introduces a Spring‑compatible download library that lets developers annotate a single method to download arbitrary objects—files, HTTP resources, or custom objects—while handling caching, concurrent loading, compression, and reactive response writing for both MVC and WebFlux environments.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Concept-Download: A Spring‑Based Library for Simplified File Download, Compression and Reactive Streaming

The article starts by pointing out that download functionality is common yet often cumbersome, especially when a project needs to export many files such as device QR‑code images into a zip archive. The author created a library to simplify this by allowing a single @Download annotation to describe the source and filename.

Typical usage is shown with a controller method:

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

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

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

For a more complex scenario—exporting device QR‑code images—the library can return a list of domain objects annotated with @SourceObject and @SourceName, letting the framework resolve the download source and filename automatically:

@Download(filename = "二维码.zip")
@GetMapping("/download")
public List
download() { return deviceService.all(); }

public class Device {
    private String name;
    @SourceObject
    private String qrCodeUrl;
    @SourceName
    public String getQrCodeName() { return name + ".png"; }
}

The core design consists of a reactive processing pipeline inspired by Spring Cloud Gateway. Each step implements DownloadHandler and is linked through a DownloadHandlerChain . A shared DownloadContext carries intermediate data, and factories such as SourceFactory create concrete Source objects (e.g., FileSource , HttpSource ) based on the input type.

To bridge MVC and WebFlux, a ReactiveDownloadFilter stores the current request and response in the Reactor context, while ReactiveDownloadResponse adapts a ServerHttpResponse to an OutputStream using a FluxSinkOutputStream that writes byte arrays as DataBuffer s.

public class ReactiveDownloadResponse implements DownloadResponse {
    private final ServerHttpResponse response;
    private OutputStream os;
    private Mono
mono;
    // write method creates FluxSinkOutputStream and forwards bytes
}

Compression is abstracted by SourceCompressor , with a default ZIP implementation. The library supports in‑memory compression or file‑based temporary storage, and the compression format can be customized via the SourceCompressor interface.

Writing the response is handled by DownloadWriter , which can process ranges, character sets, and progress callbacks. The writer receives an InputStream from the loaded source and writes to the adapted output stream.

Event publishing ( DownloadEventPublisher ) and listeners ( DownloadEventListener ) replace the earlier fixed‑listener approach, allowing flexible extension of logging, metrics, or custom actions at any stage of the download pipeline.

Finally, the author discusses pitfalls such as context lifecycle in WebFlux (the need to trigger cleanup in doAfterTerminate ) and acknowledges that while the reactive part is still a learning area, the library demonstrates advanced Spring techniques for building a highly extensible download solution.

JavaSpringReactive Programmingfile downloadAnnotationWebFluxcompression
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.