一、Servlet技术概述
1.1 Servlet定义与定位
Servlet(Server Applet)是用Java编写的服务器端程序,主要用于处理客户端请求并生成动态Web内容。作为Java EE规范的核心组件,Servlet具有以下核心特性:
- 请求/响应模型:基于HTTP协议处理客户端请求
- 平台无关性:遵循"Write Once, Run Anywhere"原则
- 高效性:多线程处理机制提升并发性能
- 扩展性:通过Filter和Listener实现功能扩展
1.2 Servlet与CGI对比
| 特性 | Servlet | CGI |
|---|---|---|
| 进程模型 | 多线程共享内存 | 每次请求创建新进程 |
| 执行效率 | 高 | 低 |
| 平台依赖 | 无(Java字节码) | 依赖具体语言实现 |
| 资源消耗 | 低 | 高 |
二、Servlet开发全流程
2.1 开发步骤详解
- 创建Servlet类:继承
HttpServlet - 重写服务方法:
doGet()/doPost() - 配置访问路径:注解或web.xml
- 部署到容器:打包为WAR文件
- 访问测试:通过URL验证功能
2.2 注解方式配置示例
@WebServlet(
name = "HelloServlet",
urlPatterns = {"/hello", "/greeting"},
loadOnStartup = 1,
initParams = {
@WebInitParam(name = "encoding", value = "UTF-8")
}
)
public class HelloServlet extends HttpServlet {
// Servlet实现
}
三、Servlet继承体系
3.1 核心类继承结构
+--------------------+
| Servlet |
+---------+----------+
^
|
+---------+----------+
| GenericServlet |
+---------+----------+
^
|
+---------+----------+
| HttpServlet |
+--------------------+
3.2 核心方法说明
| 方法 | 说明 |
|---|---|
| init(ServletConfig) | 初始化阶段调用 |
| service() | 处理请求的核心方法 |
| destroy() | 销毁前执行资源回收 |
| doGet() | 处理GET请求 |
| doPost() | 处理POST请求 |
四、Servlet生命周期管理
4.1 生命周期阶段解析
- 加载与实例化:容器加载Servlet类并创建实例
- 初始化:调用
init()方法完成配置 - 请求处理:通过
service()方法处理请求 - 销毁阶段:调用
destroy()释放资源
graph TD
A[类加载] --> B[实例化]
B --> C[初始化 init]
C --> D{请求到达}
D -->|是| E[处理请求 service]
E --> D
D -->|容器关闭| F[销毁 destroy]
4.2 生命周期控制技巧
- 加载时机控制:通过
loadOnStartup配置预加载 - 初始化参数:使用
@WebInitParam传递配置 - 资源回收:在
destroy()中关闭数据库连接等资源
五、核心API详解
5.1 ServletConfig接口
核心功能:
- 获取Servlet初始化参数
- 获取ServletContext对象
- 获取Servlet名称
典型应用:
public void init(ServletConfig config) {
String encoding = config.getInitParameter("encoding");
// 初始化编码配置
}
5.2 ServletContext接口
全局作用域功能:
- 共享应用级数据
- 访问资源文件
- 记录日志
- 获取服务器信息
使用示例:
// 设置全局属性
getServletContext().setAttribute("appVersion", "1.0.0");
// 获取资源流
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/config.xml");
六、请求响应处理机制
6.1 HttpServletRequest解析
核心功能方法:
| 方法 | 功能说明 |
|---|---|
| getParameter() | 获取请求参数 |
| getHeader() | 获取请求头信息 |
| getSession() | 获取或创建Session对象 |
| getRequestDispatcher() | 获取请求转发器 |
| setAttribute() | 设置请求域属性 |
多部分请求处理:
if (request.getContentType() != null
&& request.getContentType().startsWith("multipart/form-data")) {
Part filePart = request.getPart("file");
filePart.write("/uploads/" + getFileName(filePart));
}
6.2 HttpServletResponse控制
响应控制方法:
| 方法 | 功能说明 |
|---|---|
| setContentType() | 设置响应内容类型 |
| setCharacterEncoding() | 设置字符编码 |
| getWriter() | 获取字符输出流 |
| sendRedirect() | 重定向响应 |
| addCookie() | 添加Cookie到响应头 |
文件下载实现:
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"report.pdf\"");
try (InputStream in = new FileInputStream(file);
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
七、请求转发与重定向
7.1 请求转发(Forward)
特点:
- 服务器端行为
- 客户端无感知
- 共享Request对象
- URL保持不变
实现方式:
RequestDispatcher dispatcher = request.getRequestDispatcher("/result");
dispatcher.forward(request, response);
7.2 响应重定向(Redirect)
特点:
- 客户端行为
- 产生新的请求
- 不共享Request属性
- URL发生变化
实现方式:
response.sendRedirect("/new-location");
7.3 对比决策表
| 场景 | 选择方案 | 原因 |
|---|---|---|
| 保持URL隐藏实现路径 | 请求转发 | 客户端URL不变 |
| 表单重复提交防护 | 重定向 | 改变请求方式 |
| 跨应用跳转 | 重定向 | 可以指向外部URL |
| 共享请求数据 | 请求转发 | 保持Request对象 |
八、高级应用技巧
8.1 异步Servlet处理
@WebServlet(urlPatterns = "/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
AsyncContext asyncContext = request.startAsync();
CompletableFuture.runAsync(() -> {
// 长时间处理任务
asyncContext.getResponse().getWriter().write("Async result");
asyncContext.complete();
});
}
}
8.2 过滤器链应用
@WebFilter("/*")
public class LogFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
long start = System.currentTimeMillis();
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - start;
System.out.println("Request processed in " + duration + "ms");
}
}
九、性能优化建议
- 合理使用线程池:处理耗时操作
- 优化会话管理:及时失效不再使用的Session
- 启用GZIP压缩:减少网络传输量
- 缓存静态资源:合理设置缓存头
- 异步处理:应对高并发场景
通过深入理解Servlet核心机制,开发者可以构建出高性能、可扩展的Web应用程序。建议在实践过程中注意:
- 严格遵循Servlet生命周期管理资源
- 合理选择请求处理方式(转发/重定向)
- 善用过滤器实现横切关注点
- 及时跟进Servlet规范的最新发展