公司网站制作的公司沧州网络推广公司
Servlet 是 Java EE(现 Jakarta EE)中用于处理 Web 请求的核心组件。它在 Web 应用程序的服务器端运行,负责接收和处理客户端(如浏览器)的请求,并生成响应。
尽管现代Web开发更多采用SpringMVC等框架,但Servlet作为基础仍然重要,Spring MVC 的底层核心是基于 Servlet API 的,它本质上是对 Java EE Servlet 规范的进一步封装和扩展。通过这种封装,Spring MVC 提供了一个更高级别的、易于开发的 Web 框架。Spring MVC 的控制器方法基于注解的形式,简化了 Web 开发流程,但底层还是依赖于 Servlet 来处理 HTTP 请求。
下面是关于 Servlet 的详细介绍:
1. Servlet 的定义和作用
- 定义: Servlet 是一个实现了
javax.servlet.Servlet
接口的 Java 类,或者更常见的是继承HttpServlet
类。它用于处理客户端的请求并生成响应。 - 作用: 通过 Servlet,可以在服务器端动态生成内容(如 HTML、JSON、XML),并与客户端进行交互。
2. Servlet 的生命周期
Servlet 的生命周期包括以下几个阶段:
- 加载和实例化: 当 Servlet 容器启动时,它会加载 Servlet 类,并创建 Servlet 的实例。
- 初始化: 容器调用 Servlet 的
init()
方法进行初始化。此方法在 Servlet 实例创建后、处理请求之前被调用。可以在此方法中进行一次性的设置,如数据库连接的建立。 - 请求处理: 每当有请求到达 Servlet 时,容器会调用 Servlet 的
service()
方法来处理请求。service()
方法根据请求的类型(GET、POST 等)调用相应的doGet()
、doPost()
等方法。 - 销毁: 当 Servlet 容器卸载 Servlet 或容器关闭时,调用 Servlet 的
destroy()
方法。这时可以释放资源,如关闭数据库连接。
3. Servlet 接口和 HttpServlet 类
Servlet
接口:Servlet
接口是所有 Servlet 的基接口,定义了一些核心方法,如init()
、service()
和destroy()
。HttpServlet
类:HttpServlet
是Servlet
接口的实现类,提供了对 HTTP 请求的支持。它将请求类型分为 GET、POST、PUT、DELETE 等,并提供了对应的方法:doGet()
、doPost()
、doPut()
、doDelete()
等。
4. Servlet 方法
init(ServletConfig config)
: 初始化 Servlet,ServletConfig
对象包含 Servlet 的配置参数。service(ServletRequest req, ServletResponse res)
: 处理请求,并生成响应。通常由容器调用。destroy()
: 释放 Servlet 使用的资源。doGet(HttpServletRequest req, HttpServletResponse res)
: 处理 GET 请求。doPost(HttpServletRequest req, HttpServletResponse res)
: 处理 POST 请求。
5. Servlet 请求和响应
HttpServletRequest
: 提供了对客户端请求信息的访问,包括请求参数、头信息、请求方法等。HttpServletResponse
: 用于发送响应到客户端,包括设置响应内容类型、状态码、输出响应内容等。
HttpServletRequest
和 HttpServletResponse
是 Java Servlet API 中的两个核心接口,它们分别用于表示客户端发送给服务器的 HTTP 请求以及服务器发送给客户端的 HTTP 响应。在 Servlet 开发中,这两个接口被广泛用于处理 Web 应用中的请求和响应。
下面是对这两个接口的详细讲解,包括常用的方法和示例代码:
1. HttpServletRequest
详解
HttpServletRequest
接口代表客户端发送的 HTTP 请求,包含了与请求相关的所有信息,比如请求头、请求参数、请求路径、请求方法等。
常用方法
(1) 获取请求方法
String method = req.getMethod();
- 作用: 返回请求的 HTTP 方法(如
GET
、POST
、PUT
、DELETE
等)。
(2) 获取请求参数
String paramValue = req.getParameter("paramName");
- 作用: 用于获取客户端通过 URL、表单提交等方式发送的请求参数。
- 注意: 如果参数名在请求中不存在,返回
null
。
(3) 获取请求路径
String requestURI = req.getRequestURI();
- 作用: 返回请求的资源路径,通常用于确定客户端请求了哪个资源。例如
/myapp/index.jsp
。
(4) 获取请求头信息
String userAgent = req.getHeader("User-Agent");
- 作用: 用于获取请求头中的某些信息,比如客户端的浏览器信息、Cookies、Referer 等。
(5) 获取客户端 IP 地址
String clientIp = req.getRemoteAddr();
- 作用: 返回客户端的 IP 地址,通常用于记录或安全检查。
(6) 获取请求体内容
- 如果客户端发送的是 POST 请求,并且包含了请求体(如表单数据或 JSON),可以通过以下方法读取请求体内容:
BufferedReader reader = req.getReader();
String line;
while ((line = reader.readLine()) != null) {// 读取请求体中的内容
}
(7) 获取请求的上下文路径
String contextPath = req.getContextPath();
- 作用: 返回 Web 应用的上下文路径,在一个应用中通常是它的根路径。比如
/myapp
。
(8) 获取请求的 URL 参数
String queryString = req.getQueryString();
- 作用: 返回 URL 中的查询字符串部分。例如对于 URL
/myapp/resource?id=123&name=Tom
,返回id=123&name=Tom
。
示例代码
@WebServlet("/myservlet")
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求方法String method = req.getMethod();// 获取请求参数String param = req.getParameter("name");// 获取请求路径String requestURI = req.getRequestURI();// 获取客户端IPString clientIp = req.getRemoteAddr();// 处理逻辑...// 设置响应resp.getWriter().write("Request processed");}
}
2. HttpServletResponse
详解
HttpServletResponse
接口代表服务器发送给客户端的 HTTP 响应,用于生成响应数据并发送给客户端。你可以设置响应状态码、响应头、响应体等信息。
常用方法
(1) 设置响应状态码
resp.setStatus(HttpServletResponse.SC_OK);
- 作用: 设置 HTTP 响应的状态码。常见状态码包括:
SC_OK
(200):请求成功。SC_NOT_FOUND
(404):资源未找到。SC_INTERNAL_SERVER_ERROR
(500):服务器内部错误。
(2) 设置响应头
resp.setHeader("Content-Type", "text/html;charset=UTF-8");
- 作用: 设置 HTTP 响应头。常用于指定响应的内容类型、缓存策略、重定向等。
(3) 发送重定向
resp.sendRedirect("http://www.example.com");
- 作用: 通过这个方法可以让服务器将客户端重定向到另一个 URL。
(4) 设置响应内容类型
resp.setContentType("text/html;charset=UTF-8");
- 作用: 设置响应的内容类型,告诉客户端如何解释响应的数据格式。常见的内容类型包括:
text/html
:HTML 文本。application/json
:JSON 数据。image/png
:PNG 图片。
(5) 设置响应体内容
- 可以通过
PrintWriter
向客户端输出响应内容:
PrintWriter out = resp.getWriter();
out.println("<html><body>Hello, World!</body></html>");
(6) 设置响应的 Cookie
Cookie cookie = new Cookie("username", "Tom");
cookie.setMaxAge(3600); // 1小时
resp.addCookie(cookie);
- 作用: 用于向客户端设置 Cookie,客户端会存储这些 Cookie 并在下次请求时发送给服务器。
示例代码
@WebServlet("/myresponse")
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 设置响应的内容类型为 HTMLresp.setContentType("text/html;charset=UTF-8");// 设置状态码resp.setStatus(HttpServletResponse.SC_OK);// 输出响应内容PrintWriter out = resp.getWriter();out.println("<html><body>");out.println("<h1>Hello, this is the response from the server!</h1>");out.println("</body></html>");}
}
3. HttpServletRequest
和 HttpServletResponse
的关系
-
请求处理: 当客户端向服务器发送请求时,服务器会生成一个
HttpServletRequest
对象,封装该请求的所有信息(如路径、参数、请求头等),并将其传递给 Servlet 的doGet()
、doPost()
等方法。 -
响应生成:
HttpServletResponse
对象用于处理服务器要返回给客户端的响应信息。你可以通过它设置响应的状态码、响应头以及返回给客户端的数据内容。 -
示例场景:
- 客户端通过浏览器发送一个 GET 请求给服务器,服务器生成一个
HttpServletRequest
对象。 - 服务器处理请求,生成一个 HTML 页面,使用
HttpServletResponse
将该页面返回给客户端。
- 客户端通过浏览器发送一个 GET 请求给服务器,服务器生成一个
6. 配置 Servlet
web.xml
配置: 在WEB-INF/web.xml
文件中配置 Servlet 的映射。例如:<servlet><servlet-name>MyServlet</servlet-name><servlet-class>com.example.MyServlet</servlet-class> </servlet> <servlet-mapping><servlet-name>MyServlet</servlet-name><url-pattern>/myservlet</url-pattern> </servlet-mapping>
- 注解配置: 从 Servlet 3.0 开始,支持使用注解进行配置。例如:
@WebServlet("/myservlet") public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 处理 GET 请求} }
7. Cookie 详解
Cookie 是客户端与服务器之间用于存储少量数据的机制。它允许服务器在客户端(通常是浏览器)上存储数据,以便在后续请求中可以再次读取。Cookie 是在 HTTP 请求和响应中传递的,并且可以跨多个请求共享。它们常用于实现会话管理、用户追踪以及保存用户偏好等功能。
1. Cookie 的基本结构
一个 HTTP Cookie 的基本结构如下:
- 键值对:
name=value
,键值对是 Cookie 的核心,存储数据内容。 - 属性:Cookie 还可以包含其他属性,比如
expires
(过期时间)、path
(路径)、domain
(域名)等,控制 Cookie 的有效期和范围。
一个典型的 Cookie 示例:
Set-Cookie: username=JohnDoe; Expires=Wed, 09 Jun 2024 10:18:14 GMT; Path=/
这个 Cookie 在客户端存储了用户名,并指定了过期时间和有效路径。
2. Cookie 的工作原理
-
服务器设置 Cookie:当客户端第一次访问服务器时,服务器可以通过 HTTP 响应头
Set-Cookie
设置 Cookie。客户端(浏览器)接收到该响应后,会将 Cookie 存储。 -
客户端发送 Cookie:在后续的请求中,客户端会将之前存储的 Cookie 自动附加到请求的 HTTP 头部,发送给服务器。这使得服务器可以识别同一个客户端的不同请求。
-
服务器读取 Cookie:服务器可以通过
HttpServletRequest
获取客户端发送的 Cookie 信息,进行处理或验证。
3. Cookie 的常用属性
- name=value:这是 Cookie 的核心部分,表示键值对,例如
username=JohnDoe
。 - expires:表示 Cookie 的过期时间,使用 GMT 格式。例如:
Expires=Wed, 09 Jun 2024 10:18:14 GMT
。 - max-age:指定 Cookie 的存活时间(以秒为单位)。如
Max-Age=3600
,表示 Cookie 在 3600 秒(1 小时)后过期。 - domain:指定 Cookie 的适用域名,例如
Domain=example.com
,这样该域下的所有子域都可以访问此 Cookie。 - path:限制 Cookie 的适用路径。
Path=/
表示 Cookie 对整个网站有效,Path=/app
表示仅对/app
路径及其子路径有效。 - secure:指定该 Cookie 只能通过 HTTPS 连接传输,保证数据的传输安全。
- HttpOnly:指定 Cookie 只能在 HTTP 请求中传递,不能通过 JavaScript 访问,增强安全性,防止 XSS 攻击。
4. Cookie 的生命周期
-
会话 Cookie(Session Cookie):默认情况下,Cookie 是临时的,生命周期与浏览器会话一致,当浏览器关闭时,Cookie 就会被删除。这类 Cookie 不设置
Expires
或Max-Age
。 -
持久 Cookie(Persistent Cookie):通过设置
Expires
或Max-Age
属性,Cookie 可以在浏览器关闭后继续存在,直到指定的时间过期。
5. Java 中的 Cookie 操作
在 Java Servlet 中,我们通过 javax.servlet.http.Cookie
类来创建和管理 Cookie。以下是常见的操作:
5.1 创建和设置 Cookie
// 创建 Cookie 对象
Cookie cookie = new Cookie("username", "JohnDoe");// 设置 Cookie 过期时间(以秒为单位),例如 1 小时
cookie.setMaxAge(3600);// 设置 Cookie 的适用路径
cookie.setPath("/");// 设置 Cookie 的安全性
cookie.setHttpOnly(true);// 将 Cookie 添加到响应中,发送给客户端
resp.addCookie(cookie);
5.2 读取 Cookie
// 从请求中获取所有的 Cookie
Cookie[] cookies = req.getCookies();if (cookies != null) {for (Cookie cookie : cookies) {if ("username".equals(cookie.getName())) {String username = cookie.getValue();System.out.println("Username: " + username);}}
}
5.3 删除 Cookie
删除 Cookie 的方法是设置它的过期时间为 0。
Cookie cookie = new Cookie("username", "");
cookie.setMaxAge(0); // 设置过期时间为 0
cookie.setPath("/"); // 需要设置相同的路径才能删除
resp.addCookie(cookie);
6. 常见的使用场景
-
会话管理:Cookie 常用于会话管理,例如用户登录时,服务器可以生成一个唯一的会话 ID(Session ID),并将其存储在客户端的 Cookie 中。在后续的请求中,客户端会携带这个会话 ID,服务器就可以识别出当前的用户。
-
保存用户偏好:Cookie 也常用于保存用户的偏好设置,例如语言选择、主题颜色等。下次用户访问网站时,Cookie 可以提供这些信息,服务器据此进行个性化展示。
-
跟踪用户行为:一些广告公司和分析工具使用 Cookie 跟踪用户在不同网站上的行为,以便投放个性化广告。
8. Session 详解
Session(会话)是在客户端与服务器之间保持的会话状态管理机制,用于存储用户在浏览器与服务器进行交互期间的状态信息。Session 通常与 Cookie 配合使用,但它比 Cookie 更加安全,因为会话数据通常存储在服务器端,而客户端只是保存一个会话 ID。
1. Session 的基本概念
Session 是服务器为每个用户创建的独立会话,用来保存该用户的相关信息。在用户访问网站时,服务器会生成一个唯一的会话标识(Session ID),并将其发送给客户端。客户端随后会在每次请求时通过 Cookie 或 URL 携带该 Session ID,服务器可以根据这个 ID 找到相应的会话数据,进而为用户提供个性化的服务。
Session 与 Cookie 的区别:
- 存储位置:Session 数据存储在服务器端,而 Cookie 数据存储在客户端(浏览器)。
- 安全性:Session 更安全,因为数据不存储在客户端,防止被用户篡改。而 Cookie 的数据暴露在客户端,容易被恶意修改。
- 大小限制:Session 没有大小限制,而 Cookie 每个键值对的大小一般不超过 4KB。
- 生命周期:Session 一般在会话结束或超时后失效,Cookie 可以设置长期有效。
2. Session 的工作原理
-
客户端发起请求:用户第一次访问服务器时,服务器根据请求创建一个新的会话(Session),并生成一个唯一的 Session ID。
-
服务器生成 Session ID:服务器将生成的 Session ID 返回给客户端,通常以 Cookie 的形式发送给浏览器,存储在
Set-Cookie
头部字段中。 -
客户端保存 Session ID:浏览器会保存这个 Session ID,并在后续请求中将其包含在 HTTP 请求的 Cookie 中,发送给服务器。
-
服务器识别 Session ID:每次客户端请求时,服务器通过 Session ID 来查找并恢复该用户的会话状态。服务器会根据 Session ID 来访问保存在服务器端的会话数据。
-
会话结束:会话可以在浏览器关闭时、用户登出时、或服务器设置的超时时间到达后自动结束。
3. Session 的生命周期
-
创建:当客户端第一次访问服务器时,服务器会为该客户端创建一个新的 Session 对象,并生成一个唯一的 Session ID。这个 ID 通常通过
JSESSIONID
Cookie 存储在客户端。 -
存活:Session 默认的存活时间与用户的浏览器会话一致,用户关闭浏览器后,Session 失效。不过,也可以通过配置来改变其存活时间。
-
销毁:
- 服务器超时:如果用户长时间未访问服务器,Session 会自动超时并销毁。这个超时时间可以在服务器配置中设置,例如 Tomcat 中的
web.xml
。 - 用户登出:服务器可以在用户登出时手动销毁该用户的 Session。
- 浏览器关闭:会话结束通常伴随着浏览器关闭,虽然这不是严格的规则。
- 服务器超时:如果用户长时间未访问服务器,Session 会自动超时并销毁。这个超时时间可以在服务器配置中设置,例如 Tomcat 中的
4. Java 中的 Session 操作
在 Java Servlet 中,使用 HttpSession
接口来操作会话数据。
4.1 获取 HttpSession
每当用户发送请求时,Servlet 可以通过 HttpServletRequest
对象获取当前用户的 Session:
HttpSession session = request.getSession();
request.getSession()
:如果当前会话不存在,会创建一个新的会话对象。request.getSession(false)
:如果当前会话不存在,返回null
。
4.2 设置 Session 数据
可以通过 HttpSession
的 setAttribute
方法将数据存储到会话中:
HttpSession session = request.getSession();
session.setAttribute("username", "JohnDoe"); // 将用户名存储到 Session
4.3 获取 Session 数据
使用 getAttribute
方法获取会话中存储的数据:
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username"); // 获取存储的用户名
4.4 删除 Session 数据
使用 removeAttribute
方法可以移除会话中的某个属性:
HttpSession session = request.getSession();
session.removeAttribute("username"); // 移除存储的用户名
4.5 设置 Session 失效时间
可以通过 setMaxInactiveInterval
方法设置 Session 的超时时间(单位:秒):
HttpSession session = request.getSession();
session.setMaxInactiveInterval(1800); // 设置会话30分钟后失效
4.6 手动销毁 Session
通过 invalidate
方法可以手动销毁会话:
HttpSession session = request.getSession();
session.invalidate(); // 销毁会话
5. Session 作用域
Session 是 Servlet/JSP 中的一种作用域,用于存储跨多个请求的数据。与其他作用域相比,Session 的作用域更大,因为它在整个用户会话期间都是有效的。
- Request 作用域:仅在一个 HTTP 请求中有效。
- Session 作用域:在整个用户会话期间有效,跨越多个 HTTP 请求。
- Application 作用域:在整个 Web 应用程序的生命周期中有效,对所有用户共享。
- Page 作用域:仅在当前 JSP 页面的范围内有效。
6. Session 和 Cookie 的配合使用
Session 的工作依赖于 Cookie 来保存 Session ID。浏览器会将服务器返回的 JSESSIONID
Cookie 保存下来,后续每次请求都会自动附带这个 Cookie,从而服务器可以根据这个 ID 识别出用户的会话。
如果客户端禁用了 Cookie,Session 仍然可以通过 URL 重写机制传递 Session ID。即在 URL 中添加 ;jsessionid=xxxxxx
来传递会话 ID,但这并不常用,因为暴露在 URL 中的会话 ID 可能带来安全问题。
7. Session 的常见使用场景
-
用户登录认证:在用户登录成功后,将用户的信息(例如用户 ID 或用户名)存储在 Session 中,这样用户在访问后续页面时,服务器可以通过 Session 识别出当前用户的身份。
-
购物车管理:在线商城中,Session 常用于保存用户的购物车信息,即使用户在多个页面间跳转,购物车的内容也能保持不变。
-
个性化设置:通过 Session 保存用户的个性化设置(如语言、主题等),使得用户在多个页面中保持一致的体验。
8. Session 的优缺点
优点:
- 服务器端存储:数据存储在服务器上,更安全,用户无法轻易篡改。
- 状态保持:在多个请求之间保持用户状态,方便管理用户信息和操作。
- 跨页面共享:Session 可以跨多个页面共享数据,适合用来存储较大的、敏感的或需要跨页面共享的信息。
缺点:
- 服务器开销:Session 数据存储在服务器上,随着用户量增大,服务器的内存消耗也会增加。
- 依赖 Cookie 或 URL 重写:Session 通常依赖于 Cookie,如果客户端禁用了 Cookie,就需要使用其他机制传递 Session ID。
- 失效控制:需要合理设置 Session 的失效时间,避免用户会话超时问题或服务器负载增加。
9. 作用域
1. Request 作用域
- 作用范围:Request 作用域的数据仅在一次请求内有效,通常用于当前请求过程中多个组件(如 Servlet 或 JSP)之间的数据共享。
- 生命周期:数据在请求开始时创建,在请求结束时销毁。
- 典型场景:从一个 Servlet 转发到另一个 Servlet 或 JSP,并传递数据。
常用方法:
setAttribute(String name, Object value)
:将数据存入 request 作用域。getAttribute(String name)
:从 request 作用域获取数据。removeAttribute(String name)
:从 request 作用域移除数据。
示例:
@WebServlet("/requestScopeExample")
public class RequestScopeExample extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 将数据存入 Request 作用域req.setAttribute("message", "Hello from Request Scope!");// 转发到 JSP 进行展示req.getRequestDispatcher("/display.jsp").forward(req, resp);}
}
2. Session 作用域
- 作用范围:Session 作用域的数据对同一用户的多个请求有效,直到用户的 session 过期或被销毁。
- 生命周期:session 在第一次访问服务器时创建,并在用户不活动一段时间后(默认 30 分钟)或手动销毁时结束。
- 典型场景:用户登录后,保持用户登录状态或存储用户信息。
常用方法:
getSession()
:获取当前用户的 session(如果没有,则创建一个新的 session)。getSession(boolean create)
:获取当前 session,如果create
为false
则不会创建新 session。setAttribute(String name, Object value)
:将数据存入 session 作用域。getAttribute(String name)
:从 session 作用域获取数据。removeAttribute(String name)
:从 session 作用域移除数据。
示例:
@WebServlet("/sessionScopeExample")
public class SessionScopeExample extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取 session 对象,如果没有则创建新的HttpSession session = req.getSession();// 设置 session 作用域中的属性session.setAttribute("username", "JohnDoe");// 跳转到页面展示 session 中的数据resp.sendRedirect("displaySession.jsp");}
}
3. 不同作用域之间的区别
作用域 | 范围 | 生命周期 | 典型使用场景 |
---|---|---|---|
Request | 当前请求 | 请求开始到请求结束 | 转发数据给另一个 Servlet 或 JSP |
Session | 当前用户的所有请求 | 用户会话期间 | 保存登录信息或用户数据 |
10. ServletContext
ServletContext
是为整个 Web 应用程序提供的共享空间,所有的 Servlet 和 JSP 都可以通过它来共享数据。ServletContext
是由 Servlet 容器(如 Tomcat)创建的,在 Web 应用启动时初始化,并在 Web 应用程序停止时销毁。
1. 如何获取 ServletContext
对象
可以通过以下几种方式来获取 ServletContext
:
-
通过
HttpServlet
的getServletContext()
方法:ServletContext context = getServletContext();
-
通过
HttpServletRequest
的getServletContext()
方法:ServletContext context = req.getServletContext();
-
在
web.xml
中定义的ServletContextListener
中:
在contextInitialized()
方法中可以获取ServletContext
。public class MyContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {ServletContext context = sce.getServletContext();} }
2. ServletContext
的主要功能
2.1 共享数据
ServletContext
允许在整个应用程序范围内共享数据。它提供了 setAttribute()
和 getAttribute()
方法,用于存储和检索共享的数据。
-
存储数据:
ServletContext context = getServletContext(); context.setAttribute("myData", "Some shared data");
-
检索数据:
String data = (String) getServletContext().getAttribute("myData");
-
删除数据:
getServletContext().removeAttribute("myData");
2.2 访问初始化参数
可以通过 ServletContext
获取在 web.xml
中配置的全局初始化参数(<context-param>
),这些参数在整个应用中是共享的。
-
在
web.xml
中配置初始化参数:<context-param><param-name>appName</param-name><param-value>My Application</param-value> </context-param>
-
通过
ServletContext
获取参数:String appName = getServletContext().getInitParameter("appName");
2.3 获取 Web 应用的上下文路径
可以通过 ServletContext
来获取 Web 应用程序的上下文路径(即应用在服务器上的根路径):
String contextPath = getServletContext().getContextPath();
2.4 访问 Web 应用的资源
ServletContext
可以用来访问 Web 应用程序中的静态资源(如 HTML 文件、CSS 文件等)。常见的方法包括:
-
getResource()
和getResourceAsStream()
:用于获取应用内的资源的 URL 或输入流。InputStream is = getServletContext().getResourceAsStream("/WEB-INF/config.properties");
-
获取应用部署目录的实际路径:
String realPath = getServletContext().getRealPath("/index.html");
2.5 记录日志
ServletContext
提供了一个简便的日志记录功能,可以通过 log()
方法记录应用程序运行时的日志信息。
getServletContext().log("This is a log message");
2.6 管理 Servlet 生命周期
通过 ServletContext
,可以获取到特定的 Servlet
实例,也可以获取 Servlet 的配置信息(不推荐直接使用这种方式,通常使用注解或配置文件)。
3. 作用范围
ServletContext
的作用范围是整个 Web 应用程序,也就是说在同一个 Web 应用中的所有 Servlet、JSP 和过滤器都共享同一个 ServletContext
对象。它的生命周期和 Web 应用一致,当应用程序启动时,ServletContext
对象创建;当应用程序停止时,ServletContext
对象销毁。
对比
1. Servlet 与 Spring Boot Controller 的相似点
- 注解驱动开发: 都使用注解来定义请求处理的逻辑。通过注解可以方便地将特定路径映射到某个方法或类上。
- 请求处理: 无论是 Servlet 还是 Spring Boot,核心目标都是处理客户端(浏览器、HTTP 客户端等)的请求,并生成响应。
- 路径映射: 都提供了路径映射的方式,将客户端的 HTTP 请求映射到特定的处理逻辑上。
2. Servlet 注解和 Spring Boot 注解对比
特性 | Servlet(Java EE/Jakarta EE) | Spring Boot(Spring MVC) |
---|---|---|
类注解 | @WebServlet("/path") | @RestController 或 @Controller |
请求处理方法 | doGet() 、doPost() 等 | @GetMapping("/path") 、@PostMapping("/path") 等 |
请求参数 | HttpServletRequest 、HttpServletResponse | 自动注入参数,例如 @RequestParam 、@PathVariable |
返回数据类型 | 通过 PrintWriter 输出响应数据 | 直接返回对象(如 String 、JSON ),自动序列化响应 |
依赖注入 | 手动管理对象和依赖 | 使用 Spring 的 IoC 容器自动进行依赖注入 |
配置方式 | web.xml 或注解 | 基于注解和 Spring Boot 自动配置,无需显式配置文件 |
请求类型处理 | 通过 service() 、doGet() 、doPost() | 通过 @GetMapping 、@PostMapping 等注解区分请求类型 |
3. Servlet 和 Spring Boot 的区别
-
开发复杂度:
- Servlet: 使用 Servlet 时,开发者需要手动处理请求和响应的很多细节,比如处理
HttpServletRequest
和HttpServletResponse
对象、手动解析请求参数、处理响应等。 - Spring Boot: Spring Boot 和 Spring MVC 在 Servlet 之上进行了封装和抽象,使得开发更简单。例如,你可以直接在方法上通过注解来处理 GET、POST 请求,Spring 会自动注入请求参数,并处理返回数据的序列化等工作。
- Servlet: 使用 Servlet 时,开发者需要手动处理请求和响应的很多细节,比如处理
-
请求处理方法:
- Servlet: 你通常在
doGet()
、doPost()
等方法中处理不同的 HTTP 请求。每次处理请求时,必须显式地操作HttpServletRequest
和HttpServletResponse
对象。 - Spring Boot: Spring MVC 提供了
@GetMapping
、@PostMapping
、@RequestMapping
等注解,可以直接将 HTTP 请求映射到方法中,并通过注解自动注入请求参数,例如通过@RequestParam
或@PathVariable
获取 URL 中的参数。
- Servlet: 你通常在
-
返回类型:
- Servlet: 开发者必须手动处理响应的输出,通常需要通过
PrintWriter
将内容输出到客户端。生成 JSON 或 XML 响应需要额外的序列化代码。 - Spring Boot: Spring MVC 会自动将 Java 对象转换为 JSON、XML 或其他格式,并直接返回给客户端。你只需返回一个对象,Spring 会自动处理序列化工作。例如:
@RestController public class MyController {@GetMapping("/hello")public String hello() {return "Hello, World!";} }
- Servlet: 开发者必须手动处理响应的输出,通常需要通过
-
依赖注入:
- Servlet: Servlet 本身并不提供依赖注入的功能,开发者需要手动创建和管理对象。如果使用依赖注入,通常需要配合 Spring 或其他 IoC 容器。
- Spring Boot: Spring Boot 使用 Spring 框架的 IoC 容器,支持强大的依赖注入功能。你可以使用
@Autowired
、@Service
、@Repository
等注解来简化依赖管理。
4. Servlet 和 Spring Boot 的联系
Spring Boot 是建立在 Servlet 之上的,Spring MVC 是 Spring 框架中的 Web 组件,它本质上仍然依赖于 Servlet 容器来处理 HTTP 请求。因此,在 Spring Boot 应用中,底层仍然是 Servlet,但 Spring 对其进行了高级封装,使开发者可以通过更高层次的注解和方法来处理 Web 请求,而不需要关心 Servlet 的底层细节。
- Spring Boot 底层依赖 Servlet: Spring Boot 内部仍然使用 Servlet 处理 HTTP 请求,比如
DispatcherServlet
是 Spring MVC 的核心类,用于将请求分发给控制器处理。 - 简化的开发体验: Spring Boot 封装了 Servlet 的许多低级细节,通过注解简化了 Web 开发的过程,并且提供了更多的功能,比如自动配置、数据绑定、异常处理等。
总结
- Servlet 是 Java EE/Jakarta EE 的核心技术,用于处理 Web 请求,开发者需要手动处理很多细节。
- Spring Boot 基于 Servlet 之上,通过注解和封装提供了更高层次的 Web 开发体验,简化了请求处理、依赖管理和数据绑定。
- 这两者在设计上有相似之处(比如注解驱动开发),但 Spring Boot 更注重开发的简便性和功能的完整性。