HttpServletResponse 是 JavaWeb 三大对象之一,与 HttpServletRequest 相辅相成:前者封装客户端的所有请求数据,后者封装服务器对客户端的所有响应数据。作为服务器向客户端传递结果的 “桥梁”,HttpServletResponse 负责设置响应头、输出响应内容、控制响应状态、实现重定向等功能,是 JavaWeb 开发中处理响应逻辑的必备工具。

一、HttpServletResponse 概述

1. 作用

当服务器处理完客户端的请求后,需要通过 HttpServletResponse 对象将处理结果(如页面内容、数据、状态码、跳转指令等)返回给客户端,其作用包括:

  • 设置响应头信息(如 Content-Type、Refresh、Cookie 等)
  • 输出响应正文(如 HTML 内容、字符串数据、JSON 数据等)
  • 设置响应状态码(如 200 成功、404 资源不存在、500 服务器错误等)
  • 实现请求重定向(客户端跳转)
  • 解决响应中文乱码问题

2. 特性

  • 每一次请求对应一个独立的 HttpServletResponse 对象(与 request 一一对应)
  • 响应数据的发送顺序:响应头 → 响应正文
  • 一旦调用response.getWriter()response.getOutputStream()获取输出流后,就不能再修改响应头(否则会抛出异常)
  • 响应完成后,服务器会自动关闭输出流,无需手动关闭

3.  API 分类

HttpServletResponse 的方法按功能可分为 4 大类,覆盖响应处理的全场景:

功能分类 方法 作用
响应头操作 setHeader(String name, String value) 设置自定义响应头
setContentType(String type) 设置响应内容类型 + 编码(便捷方法)
setCharacterEncoding(String charset) 设置响应正文编码
setHeader("Refresh", "秒数;URL=目标路径") 定时刷新 / 重定向
响应状态码 setStatus(int sc) 设置响应状态码(如 200、302)
sendError(int sc, String msg) 发送错误状态码 + 自定义提示信息
响应正文输出 getWriter() 获取字符输出流(输出文本、HTML、JSON 等)
getOutputStream() 获取字节输出流(输出图片、文件等二进制数据)
重定向 sendRedirect(String location) 实现客户端跳转(应用)

二、功能实战

1. 实战 1:输出响应正文 + 解决中文乱码(基础)

向客户端输出文本或 HTML 内容是响应对象最常用的功能,难点是解决中文乱码问题,需保证响应编码与浏览器解码一致(推荐 UTF-8)。

1  Servlet(ResponseDataServlet.java)

包名:cn.tx.servlet,实现输出普通文本、HTML 标签、中文内容:

package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ResponseDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 解决响应中文乱码(必须在获取输出流之前设置!)
        // 方式1:推荐(一步到位,同时设置响应类型和编码)
        response.setContentType("text/html;charset=UTF-8");
        // 方式2:分步设置(与方式1等效,便于理解)
        // response.setCharacterEncoding("UTF-8"); // 设置响应正文编码
        // response.setHeader("Content-Type", "text/html;charset=UTF-8"); // 设置响应头

        // 1. 获取字符输出流(输出文本、HTML等字符数据)
        PrintWriter out = response.getWriter();

        // 2. 输出普通文本
        out.write("Hello HttpServletResponse!<br/>");

        // 3. 输出中文(验证无乱码)
        out.write("响应对象中文输出测试!<br/>");

        // 4. 输出HTML标签(浏览器会自动解析)
        out.write("<h3>这是响应输出的H3标题</h3>");
        out.write("<p style='color: red;'>这是红色的段落文本</p>");

        // 5. 输出变量(模拟动态数据)
        String username = "张三";
        int age = 25;
        out.write("<p>用户名:" + username + ",年龄:" + age + "</p>");

        // 注意:输出流无需手动关闭,服务器响应完成后会自动关闭
    }
}
2 配置 web.xml
<!-- 注册响应数据Servlet -->
<servlet>
    <servlet-name>ResponseDataServlet</servlet-name>
    <servlet-class>cn.tx.servlet.ResponseDataServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ResponseDataServlet</servlet-name>
    <url-pattern>/response/data</url-pattern>
</servlet-mapping>
3 运行验证

访问地址:http://localhost:8080/javaweb0315/response/data

  • 页面正确显示普通文本、中文内容、HTML 格式化标签
  • 中文无乱码,证明编码设置生效
  • 规律:响应编码设置必须在获取输出流(getWriter ())之前,否则编码设置无效

2. 实战 2:设置响应头(定时刷新 / 重定向)

响应头是服务器向客户端传递额外信息的载体,常用场景包括定时刷新、定时跳转、设置缓存策略等,文档重点强调Refresh响应头的使用。

1 Servlet(ResponseHeaderServlet.java)
package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ResponseHeaderServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 测试1:设置自定义响应头(可在浏览器F12→网络→响应头中查看)
        response.setHeader("My-Custom-Header", "JavaWeb-Response-Demo");
        out.write("已设置自定义响应头,可通过浏览器开发者工具查看<br/>");

        // 测试2:定时刷新(5秒后刷新当前页面)
        // response.setHeader("Refresh", "5");
        // out.write("5秒后自动刷新当前页面...<br/>");

        // 测试3:定时重定向(5秒后跳转到百度,文档重点案例)
        response.setHeader("Refresh", "5; URL=https://www.baidu.com");
        out.write("5秒后自动跳转到百度首页...<br/>");
        out.write("如果不想等待,可点击<a href='https://www.baidu.com'>立即跳转</a>");
    }
}
2 配置 web.xml
<!-- 注册响应头Servlet -->
<servlet>
    <servlet-name>ResponseHeaderServlet</servlet-name>
    <servlet-class>cn.tx.servlet.ResponseHeaderServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ResponseHeaderServlet</servlet-name>
    <url-pattern>/response/header</url-pattern>
</servlet-mapping>
3 运行验证

访问地址:http://localhost:8080/javaweb0315/response/header

  • 页面显示提示语,5 秒后自动跳转到百度
  • 打开浏览器 F12→网络→找到当前请求→查看 “响应头”,可看到自定义响应头My-Custom-Header: JavaWeb-Response-Demo
  • 注释掉定时重定向代码,可测试定时刷新功能(5 秒后页面重新加载)

3. 实战 3:设置响应状态码(错误处理)

响应状态码是服务器向客户端返回的 “请求处理结果标识”,常用状态码包括 200(成功)、302(重定向)、404(资源不存在)、500(服务器错误)等,文档要求掌握sendError()方法的使用。

1 Servlet(ResponseStatusServlet.java)
package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ResponseStatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 方式1:直接设置状态码(仅设置,不跳转错误页面)
        response.setStatus(200); // 200表示请求处理成功(默认就是200,可省略)
        out.write("状态码设置为200,请求处理成功!<br/>");

        // 方式2:发送错误状态码+自定义提示信息(重点)
        // 场景:模拟资源不存在,返回404错误
        // response.sendError(404, "您访问的资源不存在,请检查URL是否正确!");

        // 场景:模拟服务器内部错误,返回500错误
        // response.sendError(500, "服务器内部错误,请联系管理员!");
    }
}
2 配置 web.xml
<!-- 注册响应状态码Servlet -->
<servlet>
    <servlet-name>ResponseStatusServlet</servlet-name>
    <servlet-class>cn.tx.servlet.ResponseStatusServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ResponseStatusServlet</servlet-name>
    <url-pattern>/response/status</url-pattern>
</servlet-mapping>
3 运行验证
  1. 访问地址:http://localhost:8080/javaweb0315/response/status,页面显示 “状态码设置为 200,请求处理成功!”
  2. 注释掉方式 1 代码,解开方式 2 中 404 错误的注释,重新访问:页面显示 Tomcat 默认 404 错误页面,同时显示自定义提示信息 “您访问的资源不存在,请检查 URL 是否正确!”
  3. 同理,解开 500 错误注释,可测试服务器内部错误的响应效果

4. 实战 4:应用 —— 重定向(sendRedirect ())

重定向是 Response 最核心的应用之一,属于客户端跳转,服务器通过发送 302 状态码和目标路径,让客户端重新发起请求,文档要求熟练掌握并与请求转发区分。

1 重定向原理
  1. 客户端发起请求到 Servlet1
  2. Servlet1 调用response.sendRedirect(目标路径),服务器返回 302 状态码 + 目标路径
  3. 客户端收到响应后,自动重新发起请求到目标路径
  4. 服务器处理新请求并返回结果,整个过程属于两次请求
2 编写 Servlet(ResponseRedirectServlet.java)
package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ResponseRedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 尝试向request域设置数据(验证重定向无法共享request域数据)
        request.setAttribute("msg", "重定向测试的域数据");

        // 2.重定向(重点方法:response.sendRedirect())
        // 注意:重定向是客户端跳转,路径必须加【项目名】(与请求转发的区别)
        String contextPath = request.getContextPath(); // 动态获取项目名(/javaweb0315)

        // 方式1:重定向到项目内部资源(推荐,动态路径,避免硬编码)
        response.sendRedirect(contextPath + "/response/data");

        // 方式2:重定向到外部网站(跨域跳转,请求转发无法实现)
        // response.sendRedirect("https://www.baidu.com");

        // 方式3:硬编码项目名(不推荐,项目名修改后需手动修改)
        // response.sendRedirect("/javaweb0315/response/data");
    }
}
3 配置 web.xml
<!-- 注册重定向Servlet -->
<servlet>
    <servlet-name>ResponseRedirectServlet</servlet-name>
    <servlet-class>cn.tx.servlet.ResponseRedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ResponseRedirectServlet</servlet-name>
    <url-pattern>/response/redirect</url-pattern>
</servlet-mapping>
4 运行验证

访问地址:http://localhost:8080/javaweb0315/response/redirect

  • 效果 1:地址栏从/response/redirect变为/response/data(客户端跳转,地址栏改变)
  • 效果 2:跳转到ResponseDataServlet的页面,但无法获取request 域中设置的msg数据(重定向是两次请求,request 域失效)
  • 效果 3:注释掉内部跳转,测试跨域重定向到百度(请求转发无法实现跨域,重定向可以)

5. 实战 5:输出二进制数据(拓展应用)

除了文本和 HTML,Response 还可通过字节输出流getOutputStream()输出二进制数据(如图片、文件下载等),属于企业开发常用场景。

1 编写 Servlet(ResponseBinaryServlet.java)

以输出本地图片为例(需在项目WebContent下放置一张图片test.jpg):

package cn.tx.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ResponseBinaryServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 设置响应内容类型(图片类型)
        response.setContentType("image/jpeg");

        // 2. 获取图片路径(项目WebContent目录下的test.jpg)
        String realPath = getServletContext().getRealPath("/test.jpg");
        System.out.println("图片路径:" + realPath);

        // 3. 读取图片文件(字节输入流)
        FileInputStream fis = new FileInputStream(realPath);

        // 4. 获取响应字节输出流(输出二进制数据)
        OutputStream os = response.getOutputStream();

        // 5. 字节流复制:将图片数据写入响应流
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }

        // 6. 关闭输入流(输出流无需手动关闭)
        fis.close();
    }
}
2 配置 web.xml
<!-- 注册二进制响应Servlet -->
<servlet>
    <servlet-name>ResponseBinaryServlet</servlet-name>
    <servlet-class>cn.tx.servlet.ResponseBinaryServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ResponseBinaryServlet</servlet-name>
    <url-pattern>/response/binary</url-pattern>
</servlet-mapping>
3 运行验证
  1. 在项目WebContent目录下放置一张名为test.jpg的图片
  2. 访问地址:http://localhost:8080/javaweb0315/response/binary
  3. 页面正确显示图片,证明字节输出流生效

三、要点总结

1. 知识点总结

(1)响应中文乱码解决
  • 本质:服务器响应编码与浏览器解码不一致(默认 ISO-8859-1 不支持中文)
  • 解决方案:response.setContentType("text/html;charset=UTF-8")(一步到位,推荐)
  • 关键:编码设置必须在getWriter()getOutputStream()之前调用,否则无效
(2)重定向(与请求转发对比)
对比维度 重定向(response.sendRedirect ()) 请求转发(request.getRequestDispatcher ())
请求次数 两次请求(客户端重新发起) 一次请求(服务器内部跳转)
地址栏 改变(显示目标路径) 不变(显示原请求路径)
路径规则 需加项目名(客户端路径) 不加项目名(服务器内部路径)
request 域 无效(两次请求,新 request 对象) 有效(一次请求,共享 request 对象)
跨域支持 支持(可跳转到外部网站) 不支持(仅能跳转项目内部资源)
执行效率 低(两次网络请求) 高(服务器内部操作)
调用对象 Response 对象的方法 Request 对象的方法
(3)字符输出流 vs 字节输出流
输出流类型 方法 适用场景 注意事项
字符输出流 getWriter() 输出文本、HTML、JSON 等字符数据 需设置编码,避免中文乱码
字节输出流 getOutputStream() 输出图片、文件、视频等二进制数据 无需设置编码,直接输出字节数组
注意 同一响应中不能同时使用两种输出流,否则会抛出IllegalStateException异常

2. 重点问题

(1)重定向和请求转发的区别?

见上述对比表,记住:重定向是两次请求、地址栏变、跨域支持;转发是一次请求、地址栏不变、跨域不支持

(2)为什么重定向无法获取 request 域中的数据?
  • 重定向是客户端跳转,整个过程包含两次独立的 HTTP 请求
  • 第一次请求的 request 对象在响应完成后会被销毁,第二次请求会创建新的 request 对象
  • 两个 request 对象相互独立,因此无法共享数据(若需共享数据,需使用 Session 域)
(3)响应中文乱码的原因及解决方案?
  • 原因:服务器默认使用 ISO-8859-1 编码响应正文,该编码不支持中文,导致中文被解析为乱码
  • 解决方案:通过response.setContentType("text/html;charset=UTF-8")统一设置响应类型和编码,保证服务器编码与浏览器解码一致
(4)response.setContentType()response.setCharacterEncoding()的区别?
  • setCharacterEncoding(String charset):仅设置响应正文的编码(如 UTF-8),不影响响应类型;
  • setContentType(String type):同时设置响应类型和编码(如text/html;charset=UTF-8),是便捷方法,等效于:
    response.setCharacterEncoding("UTF-8");
    response.setHeader("Content-Type", "text/html;charset=UTF-8");
    
  • 开发中优先使用setContentType(),一步到位,避免遗漏。

四、地址汇总

  1. 输出响应正文 + 中文:http://localhost:8080/javaweb0315/response/data
  2. 设置响应头 + 定时跳转:http://localhost:8080/javaweb0315/response/header
  3. 设置响应状态码:http://localhost:8080/javaweb0315/response/status
  4. 重定向测试:http://localhost:8080/javaweb0315/response/redirect
  5. 输出二进制图片:http://localhost:8080/javaweb0315/response/binary

如果觉得本文对你有帮助,欢迎点赞 + 收藏 + 关注、~

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐