JSP 服务器响应

response 对象设状态码、响应头、内容类型与重定向。

Beginner
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.

Friends & Partners