Servlet API 是 Java EE(现 Jakarta EE)的核心组件,它为开发者提供了构建 Web 应用程序的基础框架。理解 Servlet API 的工作原理对掌握 Java Web 开发至关重要。
Servlet 基础与核心概念
Servlet 是在服务器端运行的小程序,用于处理客户端请求并生成动态响应。它通过 javax.servlet
和 javax.servlet.http
包中的接口和类实现功能。所有自定义 Servlet 都需继承 HttpServlet
类,并覆盖关键方法处理 HTTP 请求。
核心类关系:
Servlet
接口定义生命周期方法GenericServlet
提供协议无关的实现HttpServlet
扩展自GenericServlet
,专用于 HTTP 协议
Servlet的生命周期
想象一下 Servlet 就是 web 应用里某个专门负责处理某种请求的小模块。它的命基本就三部分:出生干活、每次服务、最后退休。首先呢,当 Web 服务器(或者叫容器,比如 Tomcat)一启动,或者第一次有请求来找你这个 Servlet 的时候,服务器就会把这个 Servlet 加载到内存里,然后调用它一个叫
init()
的方法。这个方法就像出生后的第一次准备动作,它就执行这么一次,一般在这里做些准备工作,比如连个数据库啊,读点配置文件之类的,为后面的请求处理打好基础。准备好之后,Servlet 就在那里等着了。然后呢,每次有匹配的用户请求过来,服务器会交到 Servlet 手里处理。这时 Servlet 的核心服务方法(最常见的是
service()
,或者是doGet()
,doPost
这些)就会被调用。这个方法才是真正干活的主力,它接收用户的请求数据(比如填了个表单),根据业务逻辑做些处理(比如查数据库),然后把生成的响应(比如网页结果)发回给浏览器。关键来了,一个 Servlet 实例在出生准备好之后,会一直存在,每次有新的请求来,服务器都会用这个同一个实例来处理,只不过会给每个请求分配一个单独的小帮手(线程)来调用服务方法。所以它能高效地服务一大波请求,避免了每次请求都重新生娃初始化那么费劲。最后,当服务器要关闭了,或者 Web 应用需要被卸载的时候,服务器就会给 Servlet 发送一个“退休通知”,调用它的
destroy()
方法。这个方法也只会被执行一次。Servlet 同志接到通知,就知道自己要退休了,就把当年在init()
里打开的东西(像数据库连接)关一关,把占用的资源清理清理,打扫收拾一下场地,然后优雅地离开。这之后,这个 Servlet 实例就被服务器清出内存了。这就是一个 Servlet 从出生、服务、到退休的完整流程了,核心就是只做一次初始化和清理,中间的服务是复用的。
HttpServlet
我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法.
方法名称 | 调用时机 | 主要功能 | 常用重写场景 |
---|---|---|---|
init() |
Servlet 实例化后仅调用一次 | 执行初始化逻辑(非线程安全) | 加载配置文件、建立数据库连接池 |
init(ServletConfig config) |
在 init() 前调用 |
获取容器配置信息,需调用 super.init(config) |
需要直接访问 ServletConfig 的场景 |
service(ServletRequest, ServletResponse) |
每次收到请求时调用 | 请求入口,将请求派发给对应的 doXxx() 方法 |
极少重写,用于统一预处理 |
doGet(HttpServletRequest, HttpServletResponse) |
收到 HTTP GET 请求时 | 处理资源获取请求(读取操作) | 查询数据、展示页面 |
doPost(HttpServletRequest, HttpServletResponse) |
收到 HTTP POST 请求时 | 处理资源创建请求(写操作) | 表单提交、新建数据 |
doPut(HttpServletRequest, HttpServletResponse) |
收到 HTTP PUT 请求时 | 处理完整资源更新请求 | RESTful API 资源替换 |
doDelete(HttpServletRequest, HttpServletResponse) |
收到 HTTP DELETE 请求时 | 处理资源删除请求 | RESTful API 删除资源 |
doHead(HttpServletRequest, HttpServletResponse) |
收到 HTTP HEAD 请求时 | 返回与 GET 相同的头部信息(无body) | 极少重写,默认为 doGet() 头部 |
doOptions(HttpServletRequest, HttpServletResponse) |
收到 HTTP OPTIONS 请求时 | 返回服务器支持的 HTTP 方法 | CORS 跨域配置 |
doTrace(HttpServletRequest, HttpServletResponse) |
收到 HTTP TRACE 请求时 | 返回请求的完整回显(用于诊断) | 极少使用 |
destroy() |
Servlet 销毁前调用(一次) | 释放资源、保存状态等清理工作 | 关闭数据库连接、释放线程池 |
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* HTTP方法演示Servlet
* 展示如何处理不同的HTTP请求方法(GET/POST/PUT/DELETE)
* 注意:类名拼写应为MethodServlet(原类名保留Servelt拼写)
*/
@WebServlet("/method")
public class MethodServelt extends HttpServlet {
/**
* 处理HTTP GET请求
* 适用于资源查询操作(幂等操作)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("处理GET请求");
// 设置响应内容类型为纯文本
resp.setContentType("text/plain");
// 向客户端返回"doGet"文本
resp.getWriter().write("doGet");
}
/**
* 处理HTTP POST请求
* 适用于创建新资源(非幂等操作)
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("处理POST请求");
resp.setContentType("text/plain");
// 使用println自动添加换行符
resp.getWriter().println("doPost");
}
/**
* 处理HTTP PUT请求
* 适用于更新整个资源(幂等操作)
*/
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("处理PUT请求");
resp.setContentType("text/plain");
resp.getWriter().write("doPut");
}
/**
* 处理HTTP DELETE请求
* 适用于删除资源(幂等操作)
*/
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("处理DELETE请求");
resp.setContentType("text/plain");
resp.getWriter().write("doDelete");
}
}



通过类似的方式还可以验证 doPut, doDelete 等方法,这里就不一一演示了
HttpServletRequest
方法签名 | 返回类型 | 描述 |
---|---|---|
String getParameter(String name) |
String |
获取请求中指定名称的参数值(如 URL 查询参数或表单数据)。若参数不存在则返回 null 。 |
Map<String, String[]> getParameterMap() |
Map<String, String[]> |
返回所有请求参数的键值对集合。键为参数名,值为字符串数组(支持多值参数)。 |
String[] getParameterValues(String name) |
String[] |
获取指定参数名的所有值数组(用于多选框等场景)。若无此参数则返回 null 。 |
String getHeader(String name) |
String |
获取指定名称的请求头值(如 User-Agent )。若头信息不存在则返回 null 。 |
Enumeration<String> getHeaderNames() |
Enumeration<String> |
返回所有请求头名称的枚举。 |
String getMethod() |
String |
返回 HTTP 请求方法(如 GET , POST , PUT )。 |
String getRequestURI() |
String |
获取请求的 URI(不包含协议、域名和端口,如 /app/login )。 |
StringBuffer getRequestURL() |
StringBuffer |
返回完整的请求 URL(包含协议和主机名,如 http://example.com/app/login )。 |
String getContextPath() |
String |
返回 Web 应用的上下文路径(如 /myapp )。部署在根路径时返回空字符串 "" 。 |
String getServletPath() |
String |
返回 Servlet 的映射路径(如 /login )。 |
HttpSession getSession() |
HttpSession |
获取当前会话,若不存在则创建新会话。 |
HttpSession getSession(boolean create) |
HttpSession |
获取当前会话,若 create=false 且不存在会话则返回 null 。 |
Object getAttribute(String name) |
Object |
获取请求域中存储的属性值(通过 setAttribute() 设置)。 |
void setAttribute(String name, Object value) |
void |
在请求域中设置属性(可用于转发时传递数据)。 |
void removeAttribute(String name) |
void |
移除请求域中指定属性。 |
String getQueryString() |
String |
返回 URL 中的查询字符串(如 ?id=123 ),若无则返回 null 。 |
String getRemoteAddr() |
String |
获取客户端 IP 地址。 |
int getServerPort() |
int |
返回服务器接收请求的端口号。 |
ServletInputStream getInputStream() |
ServletInputStream |
获取用于读取请求 Body 原始数据的输入流(如处理文件上传)。 |
BufferedReader getReader() |
BufferedReader |
获取用于读取请求 Body 文本的 Reader 。与 getInputStream() 互斥,不可同时调用。 |
String getContentType() |
String |
返回请求的 Content-Type 头(如 application/json )。 |
int getContentLength() |
int |
获取请求 Body 的字节长度(已废弃,推荐 getContentLengthLong() )。 |
打印请求信息
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
* 请求信息展示Servlet
* 用于显示HTTP请求的详细信息(协议、方法、URI、头信息等)
* 返回格式:HTML文本(使用<br>标签分隔)
*/
@WebServlet("/show")
public class ShowRequestServlet extends HttpServlet {
/**
* 处理HTTP GET请求
* 显示当前请求的详细信息
*
* @param req HTTP请求对象
* @param resp HTTP响应对象
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 创建StringBuilder构建HTML响应内容
StringBuilder stringBuilder = new StringBuilder();
// 添加HTML文档类型声明
stringBuilder.append("<!DOCTYPE html><html><head><title>Request Details</title></head><body>");
stringBuilder.append("<h2>HTTP请求详细信息</h2>");
// 获取并添加协议版本(如HTTP/1.1)
stringBuilder.append("协议版本: ").append(req.getProtocol()).append("<br>");
// 获取并添加HTTP方法(GET/POST等)
stringBuilder.append("请求方法: ").append(req.getMethod()).append("<br>");
// 获取并添加请求URI(不包括协议和域名)
stringBuilder.append("请求URI: ").append(req.getRequestURI()).append("<br>");
// 获取并添加查询字符串(GET参数部分)
stringBuilder.append("查询字符串: ").append(req.getQueryString()).append("<br>");
// 获取并添加上下文路径(应用根路径)
stringBuilder.append("上下文路径: ").append(req.getContextPath()).append("<br>");
stringBuilder.append("<h3>请求头信息</h3>");
// 获取所有请求头的名称枚举
Enumeration<String> headerNames = req.getHeaderNames();
// 遍历所有请求头
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
String value = req.getHeader(key); // 获取对应请求头的值
stringBuilder.append(key).append(": ").append(value).append("<br>");
}
stringBuilder.append("</body></html>");
// 设置响应内容类型为HTML
resp.setContentType("text/html; charset=utf-8");
// 将构建的HTML内容写入响应
resp.getWriter().println(stringBuilder.toString());
}
}
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/getparameter")
public class GetParameterServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username + " " + password);
resp.getWriter().write("ok");
}
}
获取 POST 请求中的参数
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 表单参数处理Servlet
* 演示传统HTML表单参数(application/x-www-form-urlencoded)的处理方式
*/
@WebServlet("/postparameter")
public class PostParameterServlet extends HttpServlet {
/**
* 处理HTTP POST请求
* 用于接收标准的HTML表单提交数据(application/x-www-form-urlencoded格式)
*
* @param request HTTP请求对象,包含客户端提交的参数
* @param response HTTP响应对象,用于向客户端返回数据
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 从请求中获取名为"username"的表单参数
// 相当于处理<input type="text" name="username">
String username = request.getParameter("username");
// 从请求中获取名为"password"的表单参数
// 相当于处理<input type="password" name="password">
String password = request.getParameter("password");
// 打印接收到的用户名和密码(生产环境应移除此输出)
System.out.println("Received credentials - " + username + ":" + password);
// 设置响应内容类型为纯文本
response.setContentType("text/plain");
// 向客户端返回"ok"响应文本
response.getWriter().println("ok");
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 请求体JSON映射类
* 用于接收客户端提交的JSON数据
*/
class Request {
public String username; // 用户名字段
public String password; // 密码字段
}
/**
* 响应体JSON映射类
* 用于向客户端返回JSON格式的响应
*/
class Response {
public boolean ok; // 操作状态标识
}
/**
* JSON参数处理Servlet
* 通过@WebServlet注解声明Servlet的访问路径
*/
@WebServlet("/json")
public class JsonParameterServlet extends HttpServlet {
/**
* 处理HTTP POST请求
* @param req HTTP请求对象
* @param resp HTTP响应对象
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 创建Jackson的JSON对象映射器
ObjectMapper mapper = new ObjectMapper();
// 从请求输入流中读取JSON数据并反序列化为Request对象
Request request = mapper.readValue(req.getInputStream(), Request.class);
// 打印接收到的用户名和密码(实际生产环境应移除)
System.out.println(request.username + " " + request.password);
// 创建响应对象
Response response = new Response();
response.ok = true; // 设置操作成功状态
// 将响应对象序列化为JSON字符串
String responseJson = mapper.writeValueAsString(response);
// 设置响应内容类型为JSON(UTF-8编码)
resp.setContentType("application/json; charset=utf-8");
// 将JSON字符串写入响应体
resp.getWriter().write(responseJson);
}
}
ps:这些示例有些细节我没进行说明,所以如果你要复现的话可能有点困难,不过重点其实还是这些方法的用法
HttpServletResponse
方法签名 | 功能描述 |
---|---|
void setStatus(int sc) |
设置 HTTP 响应状态码(如 200, 404, 500) |
void sendError(int sc, String msg) |
发送错误状态码和自定义错误消息到客户端 |
void sendError(int sc) |
发送错误状态码(无自定义消息) |
void sendRedirect(String location) |
重定向客户端到指定 URL(状态码 302) |
void setHeader(String name, String value) |
设置响应头(如 setHeader("Content-Type", "text/html") ) |
void addHeader(String name, String value) |
追加响应头(不覆盖同名 Header) |
void setContentType(String type) |
快捷设置 Content-Type 响应头(如 text/html;charset=UTF-8 ) |
void setCharacterEncoding(String charset) |
设置响应体编码(如 UTF-8),需在 setContentType() 前调用 |
ServletOutputStream getOutputStream() |
获取二进制输出流(用于图片/文件等) |
PrintWriter getWriter() |
获取字符输出流(用于文本内容) |
void setContentLength(int len) |
设置响应体长度(字节数,HTTP 头 Content-Length ) |
void addCookie(Cookie cookie) |
添加 Cookie 到响应头(Set-Cookie ) |
void setBufferSize(int size) |
设置响应缓冲区大小(字节) |
void resetBuffer() |
清除缓冲区数据(保持状态码和 Headers) |
void flushBuffer() |
强制将缓冲区内容发送到客户端 |
boolean isCommitted() |
检查响应是否已提交(数据是否已发送给客户端) |
void reset() |
重置状态码、Headers 和缓冲区内容 |
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* HTTP 状态码演示 Servlet
*
* 功能:演示如何设置 HTTP 响应状态码
* 访问路径:http://<服务器地址>:<端口>/<应用上下文>/status
*
* 示例:客户端访问时将收到状态码为200的空响应
*/
@WebServlet("/status") // Servlet 注解配置,定义访问路径
public class StatusServlet extends HttpServlet {
/**
* 处理 HTTP GET 请求
*
* @param req HttpServletRequest 对象,包含客户端请求信息
* @param resp HttpServletResponse 对象,用于设置服务器响应
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置 HTTP 响应状态码为 200 (OK)
// 说明:
// 1. 200 状态码表示请求已成功处理
// 2. 对于 GET 请求,通常表示请求的资源已返回在响应体中
// 3. 在默认配置下,空响应体将被发送(长度为0)
resp.setStatus(200);
// 💡 注意事项:
// - 仅设置状态码不会自动生成响应内容
// - 如果需要返回内容,应搭配输出流使用:
// resp.getWriter().print("成功请求内容");
// resp.getOutputStream().write(bytes);
//
// 🔧 状态码常量:推荐使用 HttpServletResponse 内置常量
// resp.setStatus(HttpServletResponse.SC_OK); // 等同于200
//
// ❌ 常见错误:
// 1. 同时设置状态码和调用 sendError()/sendRedirect() 会导致冲突
// 2. 在响应提交(数据发送到客户端)后修改状态码无效
//
// 📌 最佳实践:
// - 2xx 成功状态: setStatus() + 实体内容
// - 3xx 重定向: 使用更简洁的 sendRedirect(location)
// - 4xx/5xx 错误: 使用 sendError(sc) 方便自动处理错误页面
}
}

设置错误页面
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* HTTP 错误状态码演示 Servlet
*
* 功能:演示如何使用 sendError() 方法返回错误状态码
* 访问路径:http://<服务器地址>:<端口>/<应用上下文>/status
*
* 示例:客户端访问时将收到 404 错误响应
*/
@WebServlet("/status") // Servlet 注解配置,定义访问路径
public class StatusServlet extends HttpServlet {
/**
* 处理 HTTP GET 请求
*
* @param req HttpServletRequest 对象,包含客户端请求信息
* @param resp HttpServletResponse 对象,用于设置服务器响应
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 发送 404 错误状态码和自定义错误消息
// 说明:
// 1. sendError() 方法会:
// a) 设置指定的 HTTP 错误状态码(此处为 404)
// b) 清空响应缓冲区(丢弃之前写入的任何内容)
// c) 设置 Content-Type 为 text/html
// d) 使用服务器默认错误页面模板输出响应体
// 2. 自定义消息 "这是一个错误页面" 可能被忽略,取决于服务器实现
// - Tomcat 中会在错误页面内显示此消息
// - 其他服务器可能忽略而显示内置页面
resp.sendError(404, "这是一个错误页面");
/*
* 实际输出效果(示例):
* HTTP/1.1 404 Not Found
* Content-Type: text/html;charset=UTF-8
*
* <!DOCTYPE html>
* <html>
* <head><title>404 - 这是一个错误页面</title></head>
* <body>...</body>
* </html>
*/
/*
* 🔍 原理与细节:
* 1. 状态码设置:
* - sendError() 会自动设置状态码,不能与其他状态码方法(setStatus/sendRedirect)混用
* - 实际状态码包含在 HTTP 响应的起始行中
*
* 2. 缓冲区处理:
* - 调用后立即清除已写入缓冲区的任何内容
* - 响应被提交(isCommitted()返回true)
*
* 3. 错误消息处理:
* - 错误消息在 HttpServletRequest 中设置为属性:
* javax.servlet.error.status_code → 404
* javax.servlet.error.message → "这是一个错误页面"
* - 服务器使用这些属性生成错误页面
*
* 4. 错误页面优先级:
* a) web.xml 配置的自定义错误页面
* b) 服务器默认错误页面(如显示消息)
* c) 无处理时浏览器自带错误页面
*/
/*
* 📌 最佳实践:
* 1. RESTful API:避免使用 sendError(),推荐手动设置状态码:
* resp.setStatus(404);
* resp.getWriter().print("{\"error\":\"资源不存在\"}");
*
* 2. 自定义错误页面:
* // web.xml 配置
* <error-page>
* <error-code>404</error-code>
* <location>/error-404.html</location>
* </error-page>
*
* 3. 控制错误格式:
* // 使用请求分发器到错误处理页面
* req.setAttribute("errorMessage", "自定义错误详情");
* req.getRequestDispatcher("/error-handler.jsp").forward(req, resp);
*
* 4. 替代常量写法(推荐):
* resp.sendError(HttpServletResponse.SC_NOT_FOUND, "资源未找到");
*/
}
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 页面自动刷新演示 Servlet
*
* 功能:通过设置 Refresh 响应头实现页面定时刷新
* 访问路径:http://<服务器地址>:<端口>/<应用上下文>/refresh
*
* 效果:浏览器每隔1秒自动刷新页面,显示当前时间戳
*/
@WebServlet("/refresh") // Servlet 注解配置,定义访问路径
public class RefreshServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置 Refresh 响应头实现自动刷新
// 参数说明:刷新时间间隔(秒) + 可选重定向URL
// 当前配置:"1" 表示每秒刷新一次,不跳转到其他URL
resp.setHeader("Refresh", "1");
/*
* Refresh 响应头详解:
* 格式: <间隔秒数>[; url=<重定向地址>]
*
* 常见用法:
* 1. 纯刷新当前页面: resp.setHeader("Refresh", "3");
* 2. 定时跳转到新页面:
* resp.setHeader("Refresh", "5; url=https://example.com");
* 3. 相对路径跳转:
* resp.setHeader("Refresh", "2; url=/newpage.html");
*
* 🔔 注意:
* - Refresh 是非标准 HTTP 头,已被 W3C 推荐的标准替代方案(HTML <meta> 标签)取代
* - 但主流浏览器仍广泛支持此特性
*/
// 获取当前系统时间戳
long currentTime = System.currentTimeMillis();
// 向响应体写入时间戳
// 说明:每次刷新都会重新执行 doGet() 方法,生成最新时间
resp.getWriter().write("当前时间戳: " + currentTime);
/*
* 效果说明:
* 1. 客户端首次访问时:
* a) 设置响应头: Refresh: 1
* b) 响应体包含当前时间戳
* 2. 1秒后浏览器自动刷新页面
* 3. 每次刷新显示最新的时间戳
*
* 输出示例:
* 当前时间戳: 1721372170000
* 1秒后显示:当前时间戳: 1721372171000
*/
/*
* 💡 替代方案(HTML5 标准方式):
* 1. 返回包含 <meta http-equiv="Refresh"> 的 HTML
* 2. 示例代码:
* String html = """
* <!DOCTYPE html>
* <html>
* <head>
* <meta http-equiv="Refresh" content="1">
* </head>
* <body>"""+ currentTime + """</body>
* </html>""";
* resp.getWriter().print(html);
* 3. 优势:兼容性更好,遵循 W3C 规范
*
* ⚠️ 安全提醒:
* 1. 高频率刷新(<1秒)可能导致客户端性能问题
* 2. 避免无限刷新导致资源浪费
*
* 🚀 实用场景:
* - 实时监控仪表盘(简易版)
* - 页面维护倒计时跳转
* - 长轮询的替代方案
*/
}
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Servlet 实现类:重定向请求到指定 URL
* 通过 @WebServlet 注解声明 Servlet 的访问路径为 "/redirect"
*/
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
/**
* 处理 HTTP GET 请求
* @param req 客户端请求对象
* @param resp 服务器响应对象
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置 HTTP 状态码为 302 (临时重定向)
// 等效常量:HttpServletResponse.SC_FOUND
resp.setStatus(302);
// 设置重定向的目标 URL (强制浏览器跳转到搜狗主页)
// 注意:URL 必须包含完整的协议和域名
resp.setHeader("Location", "http://www.sogou.com");
/* 备注:
* 1. 也可以直接使用更便捷的发送重定向方法:
* resp.sendRedirect("http://www.sogou.com");
* 此方法会自动设置状态码和 Location 头
*
* 2. 实际开发中建议使用常量 HttpServletResponse.SC_FOUND 代替数字 302
*/
}
}