Resps
Resps 是响应构造工具类:把「正文 + Content-Type(可选下载头)」组装成一个 HttpResponse,控制器只负责把它返回。文本、JSON、HTML、静态文件、图片与 Office 文档导出都用同一套方法,接口不必自己拼响应头。
一、为什么用它
- 响应头集中设置:
Content-Type、Content-Disposition由工具类按内容类型写好,避免每个接口各写一份,也避免漏写导致浏览器按纯文本渲染。 - 两种入口:
HttpRequest入口新建一个响应(普通控制器方法);HttpResponse入口写回当前响应(拦截器、过滤器、SSE、以及已经拿到响应对象的分支)。 - 扩展名推断 MIME:不确定类型时按文件扩展名推断,推断不出走二进制流,不猜。
- 下载文件名自动编码:中文名、空格都能正确落到
Content-Disposition。
二、文本与数据响应
import nexus.io.tio.http.common.HttpRequest;
import nexus.io.tio.http.common.HttpResponse;
import nexus.io.tio.http.server.util.Resps;
import nexus.io.model.body.RespBodyVo;
public class TextController {
public HttpResponse html(HttpRequest request) {
return Resps.html(request, "<h1>tio-boot</h1>");
}
public HttpResponse json(HttpRequest request) {
return Resps.json(request, RespBodyVo.ok("hello"));
}
public HttpResponse txt(HttpRequest request) {
return Resps.txt(request, "plain text");
}
public HttpResponse xml(HttpResponse response) {
return Resps.xml(response, "<root/>");
}
}
| 方法 | Content-Type | 说明 |
|---|---|---|
html(request/response, body) | text/html | 页面片段或整页 |
json(request/response, body) | application/json | 对象自动序列化,String 与基本类型原样输出 |
txt(request/response, body) | text/plain | 纯文本,text(...) 是 txt 的别名 |
xml(response, body) | application/xml | 站点地图、订阅源等 |
svg(response, body) | image/svg+xml | 内联矢量图 |
js(request, body) | application/javascript | 前端脚本 |
css(request, body) | text/css | 样式表 |
string(..., charset, mimeTypeStr) | 自定义 | 需要别的类型时用它 |
带 charset 参数的重载用显式字符集替换请求默认值;string(...) 是最底层的一个,其余方法都只是给它配上固定的 MIME。
三、静态文件与错误页
import java.io.File;
import nexus.io.tio.http.common.HttpRequest;
import nexus.io.tio.http.common.HttpResponse;
import nexus.io.tio.http.server.util.Resps;
public class FileController {
public HttpResponse download(HttpRequest request) throws Exception {
return Resps.file(request, new File("files/report.pdf"));
}
public HttpResponse notFound(HttpRequest request) throws Exception {
return Resps.resp404(request);
}
}
| 方法 | 行为 |
|---|---|
file(request, File/path) | 读文件并返回;按扩展名给 Content-Type;带 Last-Modified |
try304(request, lastModified) | 命中协商缓存时返回 304,未命中返回 null 交给调用方继续 |
bytes(request/response, bytes, extension) | 已有字节、按扩展名给类型 |
resp404(...) / resp500(...) | 使用配置的错误页;没有配置页时退回内置页面 |
forward(request, path) | 服务端转发到新路径 |
fail(response, text) / error(response, text) | 分别返回 400 与 500,正文为给定文本 |
四、二进制内容与下载
不确定类型时用 bytesWithContentType;要作为附件下载时用 download,它一次性设置类型与 Content-Disposition。
import nexus.io.tio.boot.http.TioRequestContext;
import nexus.io.tio.http.common.HttpResponse;
import nexus.io.tio.http.server.util.Resps;
public class AttachController {
public HttpResponse attach(byte[] bytes) {
HttpResponse response = TioRequestContext.getResponse();
// 通用写法:类型与文件名都由调用方给出
return Resps.download(response, bytes, "application/octet-stream", "report-2026-10-03.bin");
}
public HttpResponse cover(byte[] bytes) {
HttpResponse response = TioRequestContext.getResponse();
// 图片:类型由扩展名推断
return Resps.image(response, bytes, "png");
}
}
contentDisposition(response, filename) 只追加下载头,适合已经自己设好类型的场景;文件名按 UTF-8 URL 编码,空格写成 %20,中文名在浏览器里显示为原文。
五、文档与图片的导出方法
常用类型各有一个快捷方法,内部就是「固定 Content-Type + 附件下载」,调用方只需要准备字节:
import nexus.io.tio.boot.http.TioRequestContext;
import nexus.io.tio.http.common.HttpResponse;
import nexus.io.tio.http.server.util.Resps;
public class ExportController {
public HttpResponse excel(byte[] xlsx) {
return Resps.excel(TioRequestContext.getResponse(), xlsx, "对话日志-2026-10-03.xlsx");
}
public HttpResponse pdf(byte[] pdf) {
return Resps.pdf(TioRequestContext.getResponse(), pdf, "report.pdf");
}
public HttpResponse word(byte[] docx) {
return Resps.docx(TioRequestContext.getResponse(), docx, "report.docx");
}
public HttpResponse slide(byte[] pptx) {
return Resps.pptx(TioRequestContext.getResponse(), pptx, "report.pptx");
}
}
| 方法 | Content-Type | 典型用途 |
|---|---|---|
excel(response, bytes[, filename]) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | xlsx 表格导出 |
excelXls(response, bytes, filename) | application/vnd.ms-excel | xls 老格式 |
pdf(response, bytes[, filename]) | application/pdf | 报表、票据 |
docx(response, bytes[, filename]) | application/vnd.openxmlformats-officedocument.wordprocessingml.document | 文档导出 |
doc(response, bytes[, filename]) | application/msword | 老格式文档 |
pptx(response, bytes[, filename]) | application/vnd.openxmlformats-officedocument.presentationml.presentation | 幻灯片导出 |
ppt(response, bytes[, filename]) | application/vnd.ms-powerpoint | 老格式幻灯片 |
image(response, bytes, extension[, filename]) | 按扩展名(png、jpg、gif 等) | 图片预览或图片下载 |
imagePng(response, bytes) / imageJpeg(response, bytes) | image/png / image/jpeg | 验证码、二维码这类固定格式 |
download(response, bytes, contentType, filename) | 任意 | 其他类型 |
类型常量(CONTENT_TYPE_EXCEL、CONTENT_TYPE_EXCEL_XLS、CONTENT_TYPE_DOCX、CONTENT_TYPE_PPTX)是公开字段,需要自己拼响应头或做二次封装时可以直接引用。
生成 xlsx 等文件内容属于业务侧的事:表格导出可以配合 api-table 的写入器,见EasyExcel 导出;Resps 只负责把字节和响应头送出去。
六、方法一览
| 分类 | 方法 |
|---|---|
| 文本 | html、json、txt、text、xml、svg、js、css、string |
| 文件 | file、try304、bytes |
| 二进制 | bytesWithContentType、bytesWithHeaders、imagePng、imageJpeg、image、download、contentDisposition |
| 文档导出 | excel、excelXls、pdf、docx、doc、pptx、ppt |
| 重定向 | redirect、redirectForever、redirectWithPage、forward |
| 错误 | fail、error、resp404、resp500 |
| 辅助 | getMimeTypeStr |
大多数文本与二进制方法同时提供 HttpRequest 与 HttpResponse 两个入口;文档导出与图片这几组方法以 HttpResponse 为入口,写回传入的对象并把它返回,配合 TioRequestContext.getResponse() 使用。file、css、js、redirect 走请求入口,svg、xml、fail、error 走响应入口。
七、使用要点
- 文件名带日期:同一份报表多次导出时,在文件名里带上日期或时间,避免浏览器把多次下载当成同名文件覆盖;后端只负责编码与发送。
- 响应可能被压缩:框架会对可压缩的正文做 gzip,浏览器会自动解压;用命令行客户端取文件时记得声明接受压缩,否则拿到的可能是压缩流。
- 大文件用文件路径:已经有磁盘文件时用
file(...),不要先读进字节数组再发;try304配合Last-Modified能省掉重复传输。 - 错误响应也有类型:
fail/error会带 400 / 500 状态码,正文是纯文本,调用方可以直接展示。
