Spring-web源码解析之HttpRequestHandler

本文深入探讨了Spring框架中的DefaultServletHttpRequestHandler类,解释了其如何处理HTTP请求,以及如何通过设置默认Servlet名称来转发静态资源请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring-HttpRequestHandler

基于4.1.7.RELEASE

HttpRequestHandler用于处理Http requests,其类似于一个简单的Servlet,只有一个handlerRequest方法,其处理逻辑随子类的实现不同而不同。

其实现类有

DefaultServletHttpRequestHandler

public class DefaultServletHttpRequestHandler implements HttpRequestHandler, ServletContextAware 

由于其实现了ServletContextAware,所以会被Spring的容器通知它所使用ServletContext,具体通知的时机是在设置完bean的属性之后init回调之前,

它的调用次序是在ApplicationContextAware之后的。次序如下图



而在本类中,setServletContext的主要作用是,如果当前的defaultServletName没有设置,则根据ServletContext中的DispatcherName来决定当前的defaultServletName。而这个defaultServletName是做什么用的呢?看下面这段注释

/**
 * Set the name of the default Servlet to be forwarded to for static resource requests.
 */
public void setDefaultServletName(String defaultServletName) {
   this.defaultServletName = defaultServletName;
}

设置静态资源转发的默认Servlet的name。

@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

   RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName);
   rd.forward(request, response);
}

将请求转发到默认的dispatcher中去,该dispatcher可能为多种形式的Servlet,在tomcat上则是默认为名字“default”的Servlet。


### HttpServlet 源码解析 `HttpServlet` 是 Java Servlet API 中的一个抽象类,它继承自 `GenericServlet` 类并提供了针对 HTTP 协议的具体实现[^1]。以下是关于 `HttpServlet` 源码的一些核心内容: #### 1. 继承关系 `HttpServlet` 的继承链如下所示: ```plaintext java.lang.Object ↳ javax.servlet.GenericServletjavax.servlet.http.HttpServlet ``` 这意味着 `HttpServlet` 不仅继承了 `GenericServlet` 提供的标准生命周期方法(如 `init()` 和 `destroy()`),还专门针对 HTTP 请求进行了扩展。 --- #### 2. 核心方法 `HttpServlet` 主要通过重写父类的 `service()` 方法来处理不同的 HTTP 请求类型。具体来说,`service()` 方法会根据请求的方法名(GET、POST 等)调用对应的 `doGet(HttpServletRequest req, HttpServletResponse resp)` 或 `doPost(HttpServletRequest req, HttpServletResponse resp)` 等方法[^5]。 以下是简化版的核心逻辑: ```java @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1 || needsResponse(lastModified, req)) { doGet(req, resp); // 调用子类实现的 doGet() } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } else if (method.equals(METHOD_HEAD)) { doHead(req, resp); // 调用子类实现的 doHead() } else if (method.equals(METHOD_POST)) { doPost(req, resp); // 调用子类实现的 doPost() } ... } ``` 上述代码展示了如何基于请求方法分发到具体的处理器方法中[^3]。 --- #### 3. 生命周期管理 `HttpServlet` 同样遵循标准的 Servlet 生命周期模型,即初始化 (`init`) -> 运行期服务 (`service`) -> 销毁 (`destroy`)。开发者通常不需要直接覆盖这些方法,而是专注于实现特定的 HTTP 方法处理器(如 `doGet` 和 `doPost`)。例如: ```java public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>Hello from GET</h1>"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/json"); PrintWriter out = response.getWriter(); out.println("{\"message\": \"Hello from POST\"}"); } } ``` --- #### 4. 注解支持 从 Servlet 3.0 开始引入了 `@WebServlet` 注解,用于声明和配置 Servlet 实现类,从而替代传统的 XML 配置文件 `web.xml`[^4]。例如: ```java @WebServlet(name = "myServlet", urlPatterns = "/example") public class MyServlet extends HttpServlet { ... } ``` 这使得开发更加简洁高效。 --- #### 5. 应用场景 `HttpServlet` 广泛应用于动态 Web 页面生成以及 RESTful API 设计等领域。它的典型用途包括但不限于表单提交处理、文件上传下载、JSON 数据交换等。 --- ### 总结 通过对 `HttpServlet` 源码的学习可以发现,该类的设计充分体现了面向对象编程的思想——将通用的功能集中到基类中完成,而留给子类去定义差异化的部分。这种设计模式极大地提高了代码复用性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值