HttpServletResponse 核心接口详解与实战应用
在 Java Web 开发中,当服务器接收到客户端的 HTTP 请求时,会对应创建 HttpServletRequest(请求对象)和 HttpServletResponse(响应对象)。开发者通过 HttpServletResponse 对象来控制返回给客户端的数据,包括设置响应头、状态码以及发送正文内容。
1. 响应数据的输出机制
向浏览器发送数据主要通过以下两种流对象实现:
ServletOutputStream getOutputStream():用于发送二进制数据(如图片、视频或文件下载)。PrintWriter getWriter():用于发送字符文本数据(如 HTML 或 JSON 字符串),通常会自动处理字符编码。
2. 常用响应头设置方法
通过操作响应头,可以指定内容的类型、长度以及浏览器的缓存行为:
// 设置字符集编码
response.setCharacterEncoding("UTF-8");
// 设置返回内容的 MIME 类型
response.setContentType("text/html;charset=UTF-8");
// 设置基础响应头
response.setHeader("Cache-Control", "no-cache");
// 设置日期类型的响应头
response.setDateHeader("Expires", 0);
3. HTTP 状态码常量
接口中预定义了标准 HTTP 状态码的常量,常见的包括:
SC_OK (200):请求已成功处理。SC_MOVED_TEMPORARILY (302):临时重定向。SC_BAD_REQUEST (400):客户端请求语法错误。SC_NOT_FOUND (404):服务器无法找到请求的资源。SC_INTERNAL_SERVER_ERROR (500):服务器内部错误。
4. 应用案例:实现文件下载功能
实现文件下载的核心在于设置 Content-Disposition 响应头,通知浏览器以附件形式处理流数据。
public class FileDownloadHandler extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 1. 确定文件位置与名称
String targetPath = "/data/storage/sample.pdf";
String downloadFileName = "manual.pdf";
// 2. 配置响应头,对文件名进行 URL 编码以支持中文
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(downloadFileName, "UTF-8"));
// 3. 执行流拷贝操作
File targetFile = new File(targetPath);
if (targetFile.exists()) {
try (InputStream fileInput = new FileInputStream(targetFile);
OutputStream responseOutput = response.getOutputStream()) {
byte[] chunk = new byte[4096];
int bytesRead;
while ((bytesRead = fileInput.read(chunk)) != -1) {
responseOutput.write(chunk, 0, bytesRead);
}
}
}
}
}
5. 应用案例:动态生成验证码图片
利用 Java 的绘图 API,可以在内存中创建图像并直接通过响应流输出到前端,常用于安全验证。
public class CaptchaGenerator extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 设置页面不缓存
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Cache-Control", "no-cache");
resp.setDateHeader("Expires", 0);
int imgWidth = 120, imgHeight = 40;
BufferedImage image = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 填充背景色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, imgWidth, imgHeight);
// 绘制随机验证码
g2d.setColor(Color.DARK_GRAY);
g2d.setFont(new Font("Consolas", Font.BOLD, 28));
String randomCode = String.valueOf(new Random().nextInt(899999) + 100000);
g2d.drawString(randomCode, 10, 30);
g2d.dispose();
// 将图片以 JPEG 格式输出
resp.setContentType("image/jpeg");
ImageIO.write(image, "jpg", resp.getOutputStream());
}
}