如何让StaticHandler下载所有MIME类型文件?
解决Vert.x StaticHandler强制所有文件触发下载的问题
要让所有通过StaticHandler返回的文件都触发下载,而非在浏览器中直接渲染,有两种直接可行的实现方式:
方案一:给StaticHandler全局配置下载响应头
Vert.x的StaticHandler支持通过setHeaders方法统一为所有返回文件添加响应头,只需注入Content-Disposition: attachment即可强制浏览器触发下载行为。若要保留原文件名,还可以在头信息中指定文件名参数。
修改后的完整代码如下:
public class Server extends AbstractVerticle { @Override public void start() throws Exception { Router router = Router.router(vertx); router.route().handler(BodyHandler.create()); // 初始化StaticHandler并全局设置强制下载头 StaticHandler staticHandler = StaticHandler.create("data"); staticHandler.setHeaders((headers, file) -> { // 带原文件名的下载头格式,浏览器下载时会显示对应文件名 headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName())); }); router.route("/static/*").handler(staticHandler); vertx.createHttpServer().requestHandler(router).listen(8080); } }
如果不需要显示原文件名,直接写headers.add("Content-Disposition", "attachment")即可。
方案二:通过路由上下文钩子追加响应头
如果需要在路由链中实现更灵活的控制(比如后续可扩展条件判断逻辑),可以在StaticHandler之后添加自定义处理器,在响应发送前注入下载头:
public class Server extends AbstractVerticle { @Override public void start() throws Exception { Router router = Router.router(vertx); router.route().handler(BodyHandler.create()); router.route("/static/*") .handler(StaticHandler.create("data")) .handler(ctx -> { // 获取当前请求对应的文件对象(可选,用于设置原文件名) File file = ctx.get("vertx-web.static.file"); if (file != null) { ctx.response().putHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getName())); } else { ctx.response().putHeader("Content-Disposition", "attachment"); } ctx.next(); }); vertx.createHttpServer().requestHandler(router).listen(8080); } }
这种方式利用Vert.x路由的链式处理特性,在StaticHandler完成文件定位后,统一为响应添加上下载头。
内容的提问来源于stack exchange,提问作者Lukas Weber
相关产品推荐
相关产品推荐

