Simplify File Downloads in SpringBoot with a Single @Download Annotation
The Concept‑Download library lets SpringBoot developers replace verbose download code with a single @Download annotation that automatically handles classpath resources, local files, HTTP URLs, custom objects, compression and reactive streaming, simplifying batch and QR‑code ZIP exports.
File download is a common but often cumbersome feature in Java projects. The Concept‑Download library simplifies this by allowing developers to handle any download with a single @Download annotation.
Basic usage shows a SpringBoot controller where @Download can specify a classpath resource, a local file, or an HTTP URL, eliminating boilerplate code.
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";
}
}A real‑world example demonstrates exporting QR‑code images of devices as a ZIP file. By annotating a controller method with @Download(filename = "二维码.zip") and marking fields with @SourceObject and @SourceName , the library automatically resolves file names, caching, compression and response writing.
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
downloadDevices() {
return deviceService.all();
}
}
class Device {
private String name;
@SourceObject
private String qrCodeUrl;
@SourceName
public String getQrCodeName() {
return name + ".png";
}
}The implementation relies on AOP interception and supports reactive programming via Spring WebFlux. A custom WebFilter injects the ServerHttpResponse into the reactive context.
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
filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(exchange)
.contextWrite(ctx -> ctx.put(ServerHttpResponse.class, exchange.getResponse()));
}
}Utility class ReactiveDownloadHolder retrieves the response, while the DownloadHandler chain processes tasks such as fetching sources, compressing, and streaming.
import org.springframework.web.server.ServerHttpResponse;
import reactor.core.publisher.Mono;
public class ReactiveDownloadHolder {
public static Mono
getResponse() {
return Mono.deferContextual(ctx -> Mono.just(ctx.get(ServerHttpResponse.class)));
}
}
public interface DownloadHandler {
Mono
handle(DownloadContext context, DownloadHandlerChain chain);
}Source abstraction allows the library to handle various data types (File, URL, custom objects) through a SourceFactory interface.
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);
}
}Overall, the library reduces download implementation to a few annotations, making batch downloads and custom object handling straightforward for SpringBoot 3.4 projects.
Java Tech Enthusiast
Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.