分析servlet最深层的源码读懂servlet如何实现
发布日期:2021-05-07 14:42:43 浏览次数:17 分类:原创文章

本文共 3383 字,大约阅读时间需要 11 分钟。

目录









1 Servlet 继承结构






1.1Servlet 接口


反编译工具打开看其源码解析:



代码:


package javax.servlet;import java.io.IOException;public abstract interface Servlet{  public abstract void init(ServletConfig paramServletConfig)    throws ServletException;  public abstract ServletConfig getServletConfig();  public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)    throws ServletException, IOException;  public abstract String getServletInfo();  public abstract void destroy();}

1.init(),创建 Servlet 对象后立即调用该方法完成其他初始化工作。


2.service(),处理客户端请求,执行业务操作,利用响应对象响应客户端请求。


3.destroy(),在销毁 Servlet 对象之前调用该方法,释放资源。


4.getServletConfig()ServletConfig 是容器向 servlet 传递参数的载体。


5.getServletInfo(),获取 servlet 相关信息。


1.2 ServletConfig 接口



代码:


package javax.servlet;import java.util.Enumeration;public abstract interface ServletConfig{  public abstract String getServletName();  public abstract ServletContext getServletContext();  public abstract String getInitParameter(String paramString);  public abstract Enumeration<String> getInitParameterNames();}


  Servlet 运行期间,需要一些辅助信息,这些信息可以在 web.xml 文件中,使用一个或多 个元素,进行配置。当 Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息,封装到一个 ServletConfig 对象中,通过调用 init(ServletConfig config)方法,将 ServletConfig 对称传递给 Servlet


1.3 GenericServlet 是个抽象类


代码:


package javax.servlet;import java.io.IOException;import java.io.Serializable;import java.util.Enumeration;public abstract class GenericServlet  implements Servlet, ServletConfig, Serializable{  private static final long serialVersionUID = 1L;  private transient ServletConfig config;  public void destroy()  {  }  public String getInitParameter(String name)  {    return getServletConfig().getInitParameter(name);  }  public Enumeration<String> getInitParameterNames()  {    return getServletConfig().getInitParameterNames();  }  public ServletConfig getServletConfig()  {    return this.config;  }  public ServletContext getServletContext()  {    return getServletConfig().getServletContext();  }  public String getServletInfo()  {    return "";  }  public void init(ServletConfig config)    throws ServletException  {    this.config = config;    init();  }  public void init()    throws ServletException  {  }  public void log(String msg)  {    getServletContext().log(getServletName() + ": " + msg);  }  public void log(String message, Throwable t)  {    getServletContext().log(getServletName() + ": " + message, t);  }  public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)    throws ServletException, IOException;  public String getServletName()  {    return this.config.getServletName();  }}

  GenericServlet 是实现了 Servlet 接口的抽象类。在 GenericServlet 中进一步的定义了Servlet 接口的具体实现,其设计的目的是为了和应用层协议解耦,在 GenericServlet 中包含一个 Service 抽象方法。我们也可以通过继承 GenericServlet 并实现 Service 方法实现请求的处 理 , 但是需要将 ServletReuqest ServletResponse 转为 HttpServletRequest 和HttpServletResponse。


有的人会问有什么用呢?


我HttpServlet直接实现上面三个接口不香吗?现在Http协议较为优秀但是我以后再来一个XXX协议,再来跟多XXX协议,你的代码就会非常的冗余而且很多无用代码,而采用中间接口以后不管什么协议直接继承就可以了。


1.4 HttpServlet



可以看到一个service父类和子类的方法同名:



也就是我们在写的时候会自动的转为子接口类型HttpServletRequest和Response因为他重写了GenericServlet,这个调用不是递归调用你看参数是不同的。



  继承自 GenericServlet. 针对于处理 HTTP 协议的请求所定制。在 HttpServlet service() 方法中已经把 ServletReuqest 和 ServletResponse 转 为 HttpServletRequest 和 HttpServletResponse。 直接使用 HttpServletRequest HttpServletResponse, 不再需要强转。实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可。


上一篇:Servlet 处理请求的原理
下一篇:高端的技术往往选用最朴素的方式来运行!

发表评论

最新留言

不错!
[***.144.177.141]2025年04月08日 03时24分07秒