Response
# 一、HTTP 协议
# 1. 请求消息:客户端发送给服务器端的数据
# 数据格式:
- 请求行
- 请求头
- 请求空行
- 请求体
# 2. 响应消息:服务器端发送给客户端的数据
# 数据格式:
响应行
格式:协议/版本 响应状态码 状态码描述
响应状态码:服务器告诉客户端本次请求的状态。
状态码是三位数字,常见分类:
1xx:服务器接收了请求,但还在处理
2xx:成功,例如:200
3xx:重定向,例如:
- 302:临时重定向
- 304:访问缓存
4xx:客户端错误,例如:
- 404:资源不存在
- 405:请求方式错误(找不到对应的 doXxx 方法)
5xx:服务器端错误,例如:
- 500:服务器内部异常
响应头
- 格式:头名称: 值
- 常见响应头:
- Content-Type:指定响应体数据格式与编码
- Content-Disposition:以何种方式打开响应体数据
- inline:默认,页面内打开
- attachment;filename=xxx:以附件形式下载
响应空行
响应体:实际传输的数据(HTML、图片等)
# 响应消息示例:
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMT
<html>
<head>
<title>$Title$</title>
</head>
<body>
hello , response
</body>
</html>
# 二、Response 对象
# 功能:设置响应消息
# 1. 设置响应行
response.setStatus(200); // 设置状态码
# 2. 设置响应头
response.setHeader("Content-Type", "text/html;charset=UTF-8");
# 3. 设置响应体
- 获取输出流:
- 字符输出流:
PrintWriter writer = response.getWriter();
- 字节输出流:
ServletOutputStream outputStream = response.getOutputStream();
- 输出数据至客户端
# 案例:重定向
# 实现方式
// 方法一:手动设置状态码与响应头
response.setStatus(302);
response.setHeader("location", "/day15/responseDemo2");
// 方法二:推荐使用
response.sendRedirect("/day15/responseDemo2");
# 重定向特点:
- 地址栏变化
- 可以访问其他服务器资源
- 两次请求,无法共享 request 数据
# 转发(forward)特点:
- 地址栏不变
- 只能访问当前服务器资源
- 一次请求,可以共享 request 数据
# 路径写法
# 相对路径(不能唯一定位资源):
./index.html
../admin/index.html
# 绝对路径(以 /开头,可以定位唯一资源):
request.getContextPath(); // 动态获取虚拟目录
说明:
- 若路径用于浏览器访问 → 加虚拟目录
- 若路径用于服务器内部转发 → 不加虚拟目录
# 案例:输出字符数据
// 设置响应编码(需在获取流前设置)
response.setContentType("text/html;charset=utf-8");
// 获取流并输出数据
PrintWriter writer = response.getWriter();
writer.write("你好,response!");
# 案例:输出字节数据
ServletOutputStream os = response.getOutputStream();
// 读取文件内容写入 os
# 验证码本质
- 本质:图像
- 目的:防止恶意注册或脚本提交
# 三、ServletContext 对象
# 1. 概念
代表整个 Web 应用,可以与服务器通信。
# 2. 获取方式
// 方法一:通过 request 获取
ServletContext context = request.getServletContext();
// 方法二:通过 Servlet 获取
ServletContext context = this.getServletContext();
# 3. 功能
# 1)获取 MIME 类型
String type = context.getMimeType("a.jpg"); // image/jpeg
# 2)域对象:共享数据
context.setAttribute("msg", "value");
Object val = context.getAttribute("msg");
context.removeAttribute("msg");
- 范围:全应用共享
# 3)获取服务器真实路径
String path1 = context.getRealPath("/b.txt"); // Web 根目录
String path2 = context.getRealPath("/WEB-INF/c.txt");
String path3 = context.getRealPath("/WEB-INF/classes/a.txt"); // src目录
# 四、案例:文件下载
# 需求:
- 页面提供下载超链接
- 点击后弹出下载提示框
- 下载文件(如图片)
# 分析:
- 浏览器能解析资源 → 直接打开
- 要让资源都弹出“下载框”
- 使用响应头控制:
Content-Disposition: attachment;filename=xxx.jpg
# 实现步骤:
# 1. 页面设置超链接
<a href="/downloadServlet?filename=img.jpg">下载图片</a>
# 2. Servlet 实现
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取文件名
String filename = request.getParameter("filename");
// 2. 获取真实路径
ServletContext context = this.getServletContext();
String path = context.getRealPath("/img/" + filename);
// 3. 创建文件输入流
FileInputStream fis = new FileInputStream(path);
// 4. 设置响应头(文件下载)
String mime = context.getMimeType(filename);
response.setHeader("Content-Type", mime);
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
// 5. 写出数据
ServletOutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
fis.close();
}
# 中文文件名问题
# 原因:
浏览器对响应头中的 filename 编码解析不同。
# 解决方案:
- 获取客户端浏览器类型(User-Agent)
- 判断是否为 IE、Firefox、Chrome 等
- 使用不同编码策略处理文件名
上次更新: 2025/07/23, 01:37:33