Servlet 容器是一个用于管理和执行 Java Servlet、JSP(JavaServer Pages)和其他基于 Java 的 web 组件的运行时环境。它是 Java EE(企业版)规范的一部分,负责处理客户端请求、管理 servlet 生命周期、提供网络服务和其他运行时环境支持。 ### Servlet 容器的功能 1. **请求处理**: - 接收客户端(通常是浏览器)发送的 HTTP 请求,并根据 URL 路径将请求分发到相应的 servlet 进行处理。 - 处理 HTTP 请求和响应,包括 GET、POST、PUT、DELETE 等方法。 2. **Servlet 生命周期管理**: - 管理 servlet 的生命周期,包括加载、初始化、处理请求、销毁等。 - 调用 servlet 的 init() 方法进行初始化,service() 方法处理请求,destroy() 方法进行销毁。 3. **会话管理**: - 提供会话管理功能,通过 cookies 或 URL 重写来跟踪用户会话。 - 维护会话状态,确保多次请求之间的数据一致性。 4. **安全性**: - 提供认证和授权机制,确保只有授权用户才能访问受保护的资源。 - 支持基于角色的访问控制(RBAC)。 5. **并发处理**: - 处理多个客户端请求的并发性,确保高效的资源使用和响应时间。 - 提供线程管理和同步机制,确保数据一致性和线程安全。 6. **资源管理**: - 管理静态资源(如 HTML、CSS、JavaScript 文件)和动态资源(如 servlet、JSP 页面)。 - 提供资源的加载和缓存功能,优化性能。 7. **日志记录和监控**: - 提供日志记录功能,记录请求、响应和错误信息,便于调试和监控。 - 支持监控和管理工具,帮助管理员监控服务器性能和健康状态。 ### 常见的 Servlet 容器 1. **Apache Tomcat**: - 开源的 Servlet 容器,广泛用于开发和部署 Java web 应用。 - 支持 Servlet、JSP 和 WebSocket 等规范。 2. **Jetty**: - 轻量级、高性能的 Servlet 容器,适用于嵌入式系统和微服务架构。 - 支持 HTTP/2、WebSocket 等现代协议。 3. **GlassFish**: - 完整的 Java EE 应用服务器,支持所有 Java EE 规范。 - 提供企业级功能,如事务管理、消息驱动 Bean 和 JCA 连接器等。 4. **WildFly(原 JBoss AS)**: - 另一个完整的 Java EE 应用服务器,支持所有 Java EE 规范。 - 提供高性能和高可用性的企业级功能。 5. **IBM WebSphere**: - 企业级 Java EE 应用服务器,提供高可靠性和高性能。 - 支持广泛的企业功能和集成能力。 6. **Oracle WebLogic**: - 企业级 Java EE 应用服务器,提供高可用性和可扩展性。 - 支持广泛的企业功能和集成能力。 ### Servlet 容器的工作原理 1. **启动**: - Servlet 容器启动时,读取配置文件(如 `web.xml` 或注解配置),加载和初始化所有配置的 servlet 和其他组件。 2. **请求处理**: - 当客户端发送请求时,Servlet 容器接收请求并解析 URL 路径,将请求分发到相应的 servlet。 - 调用 servlet 的 service() 方法,根据请求方法(GET、POST 等)调用 doGet() 或 doPost() 等具体方法处理请求。 3. **响应生成**: - Servlet 处理请求后,生成响应(如 HTML、JSON 数据)并通过 HttpServletResponse 对象发送回客户端。 4. **会话管理**: - Servlet 容器维护会话状态,通过 cookies 或 URL 重写跟踪用户会话。 - 提供 HttpSession 对象,允许 servlet 存储和检索会话数据。 5. **销毁**: - 在应用程序关闭或 servlet 需要卸载时,Servlet 容器调用 servlet 的 destroy() 方法进行清理工作。 ### 总结 Servlet 容器是 Java web 应用程序的核心组件,提供了请求处理、生命周期管理、会话管理、安全性、并发处理、资源管理和日志记录等功能。常见的 Servlet 容器包括 Apache Tomcat、Jetty、GlassFish、WildFly、IBM WebSphere 和 Oracle WebLogic 等。了解 Servlet 容器的工作原理和功能,有助于开发和部署高效、可靠的 Java web 应用程序。 --- 部分方法 ### `HttpServletRequest` 对象的主要用途 1. **获取请求参数**: - 使用 `getParameter(String name)` 方法获取单个请求参数的值。 - 使用 `getParameterValues(String name)` 方法获取具有相同名称的多个请求参数的值(返回字符串数组)。 - 使用 `getParameterMap()` 方法获取所有请求参数的键值对(返回 `Map`)。 ``` String username = request.getParameter("username"); String[] hobbies = request.getParameterValues("hobbies"); Map parameterMap = request.getParameterMap(); ``` 2. **获取请求头信息**: - 使用 `getHeader(String name)` 方法获取指定请求头的值。 - 使用 `getHeaders(String name)` 方法获取具有相同名称的多个请求头的值(返回 `Enumeration`)。 - 使用 `getHeaderNames()` 方法获取所有请求头的名称(返回 `Enumeration`)。 ``` String userAgent = request.getHeader("User-Agent"); Enumeration headerNames = request.getHeaderNames(); ``` 3. **获取请求路径和 URL 信息**: - 使用 `getRequestURI()` 方法获取请求的 URI 部分。 - 使用 `getRequestURL()` 方法获取请求的完整 URL。 - 使用 `getContextPath()` 方法获取应用程序的上下文路径。 - 使用 `getServletPath()` 方法获取 servlet 的路径。 ``` String uri = request.getRequestURI(); StringBuffer url = request.getRequestURL(); String contextPath = request.getContextPath(); String servletPath = request.getServletPath(); ``` 4. **获取请求方法**: - 使用 `getMethod()` 方法获取请求的方法(如 GET、POST、PUT、DELETE 等)。 ``` String method = request.getMethod(); ``` 5. **获取请求体数据**: - 使用 `getReader()` 方法获取 `BufferedReader` 对象,从而读取请求体的数据(用于处理文本数据)。 - 使用 `getInputStream()` 方法获取 `ServletInputStream` 对象,从而读取请求体的数据(用于处理二进制数据)。 ``` BufferedReader reader = request.getReader(); // 或 ServletInputStream inputStream = request.getInputStream(); ``` 6. **会话管理**: - 使用 `getSession()` 方法获取当前会话(如果不存在则创建一个新的会话)。 - 使用 `getSession(boolean create)` 方法获取当前会话(根据 `create` 参数决定是否创建新的会话)。 ``` HttpSession session = request.getSession(); ``` 7. **处理请求属性**: - 使用 `getAttribute(String name)` 方法获取请求属性。 - 使用 `setAttribute(String name, Object o)` 方法设置请求属性。 - 使用 `removeAttribute(String name)` 方法移除请求属性。 ``` Object attr = request.getAttribute("attrName"); request.setAttribute("attrName", someObject); request.removeAttribute("attrName"); ``` 8. **其他有用的方法**: - `getRemoteAddr()`:获取客户端的 IP 地址。 - `getRemoteHost()`:获取客户端的主机名。 - `getCookies()`:获取请求中的所有 cookies(返回 `Cookie[]`)。 - `getLocale()`:获取客户端的首选语言环境。 - `getQueryString()`:获取请求的查询字符串。 ``` String remoteAddr = request.getRemoteAddr(); String remoteHost = request.getRemoteHost(); Cookie[] cookies = request.getCookies(); Locale locale = request.getLocale(); String queryString = request.getQueryString(); ``` ### 示例代码 下面是一个简单的示例 servlet,展示如何使用 `HttpServletRequest` 对象获取请求信息: ``` 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.io.PrintWriter; @WebServlet("/example") public class ExampleServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); // 获取请求参数 String username = request.getParameter("username"); // 获取请求头 String userAgent = request.getHeader("User-Agent"); // 获取请求路径和 URL String uri = request.getRequestURI(); StringBuffer url = request.getRequestURL(); // 获取请求方法 String method = request.getMethod(); // 获取客户端 IP 地址 String remoteAddr = request.getRemoteAddr(); // 输出信息到响应 out.println(""); out.println("

Request Information

"); out.println("

Username: " + username + "

"); out.println("

User-Agent: " + userAgent + "

"); out.println("

Request URI: " + uri + "

"); out.println("

Request URL: " + url.toString() + "

"); out.println("

Request Method: " + method + "

"); out.println("

Client IP: " + remoteAddr + "

"); out.println(""); } } ``` ### 总结 `HttpServletRequest` 对象是处理客户端 HTTP 请求的关键对象。它提供了各种方法来访问请求参数、请求头、请求路径、会话信息和请求体数据等。通过正确使用 `HttpServletRequest` 对象,开发者可以有效地处理和响应客户端请求,构建功能丰富的 web 应用程序。