JSP 服务器响应
response 对象设状态码、响应头、内容类型与重定向。
Key Points响应头必须在任何输出之前设置;JSP 有缓冲,所以只要没 flush,setHeader 还有效。
设置响应
JSP
<%@ page contentType="text/html;charset=UTF-8" %>
<%
response.setHeader("X-App", "demo");
response.setDateHeader("Expires", 0);
response.addHeader("Cache-Control", "no-store");
%>
<!DOCTYPE html>
<html><body><p>响应头已设置</p></body></html>重定向
JSP
<%
if (session.getAttribute("uid") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
return; // 必须 return,后面不能再输出
}
%>Always return after sendRedirect. The rest of the JSP still runs, and once the container sees the redirect it throws IllegalStateException, dumping a stack trace onto the page.
下载文件
JSP
<%@ page contentType="application/octet-stream"
pageEncoding="UTF-8"
import="java.io.*, java.net.URLEncoder" %>
<%
String fname = "report.csv";
response.setHeader("Content-Disposition",
"attachment; filename*=UTF-8''" + URLEncoder.encode(fname, "UTF-8"));
try (InputStream in = application.getResourceAsStream("/WEB-INF/data/report.csv");
OutputStream os = response.getOutputStream()) {
if (in == null) {
response.sendError(404, "文件不存在");
return;
}
in.transferTo(os);
}
%>Nothing — not even a blank line — may precede <%@ page %> on a download page. Those bytes enter the response first and corrupt the file header, producing an unopenable download.
缓冲与 flush
JSP
<%@ page buffer="16kb" autoFlush="true" %>
<%
out.flush(); // 之后 response.setHeader 全部无效
%>- 默认缓冲 8KB,写满才真正发给浏览器
out.flush()或缓冲写满 = 响应已提交,头和状态码都定死了autoFlush="false"时缓冲溢出会抛异常,适合必须完整输出的场景
Discovering mid-page that you need
sendError is a common accident. Put all decisions — auth, parameters, existence — before any HTML, not in the middle of a table.设置响应
JSP
<%@ page contentType="text/html;charset=UTF-8" %>
<%
response.setHeader("X-App", "demo");
response.setDateHeader("Expires", 0);
response.addHeader("Cache-Control", "no-store");
%>
<!DOCTYPE html>
<html><body><p>响应头已设置</p></body></html>重定向
JSP
<%
if (session.getAttribute("uid") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
return; // 必须 return,后面不能再输出
}
%>sendRedirect 之后必须 return。JSP 的后续 HTML 仍会被执行,容器发现已重定向就会抛 IllegalStateException,页面上出现一大段堆栈。
下载文件
JSP
<%@ page contentType="application/octet-stream"
pageEncoding="UTF-8"
import="java.io.*, java.net.URLEncoder" %>
<%
String fname = "report.csv";
response.setHeader("Content-Disposition",
"attachment; filename*=UTF-8''" + URLEncoder.encode(fname, "UTF-8"));
try (InputStream in = application.getResourceAsStream("/WEB-INF/data/report.csv");
OutputStream os = response.getOutputStream()) {
if (in == null) {
response.sendError(404, "文件不存在");
return;
}
in.transferTo(os);
}
%>下载页里**不能有任何空白或换行在 <%@ page %> 之前**,否则那些字节会先被写进响应,文件头就坏了,下载下来打不开。这类页面应该整行紧贴文件开头写。
缓冲与 flush
JSP
<%@ page buffer="16kb" autoFlush="true" %>
<%
out.flush(); // 之后 response.setHeader 全部无效
%>- 默认缓冲 8KB,写满才真正发给浏览器
out.flush()或缓冲写满 = 响应已提交,头和状态码都定死了autoFlush="false"时缓冲溢出会抛异常,适合必须完整输出的场景
长页面写到一半才发现要
sendError 是常见事故。判断逻辑(权限、参数、数据存在性)必须放在页面最前面、任何 HTML 之前,别等渲染到表格中间才报错。