B/S结构学习过程中涉及到一个基本的问题,即:项目是如何通过浏览器中输入的url地址,从程序中获取响应内容,并将响应内容返回至页面?
关于上面的问题,涉及浏览器与tomcat服务器之间的信息传递。浏览器作为请求端,将请求发送的数据以固定的格式传递给tomcat;tomcat将请求过来的数据转化为内置的HttpServletRequest类,并对请求信息进行处理响应,生成所需的数据,即响应对象HttpServletResponse,设置响应对象中的一些属性,将对象传递给浏览器,便于浏览器解析并呈现数据。
上述过程中涉及到的请求格式、响应格式,涉及知识点Http协议;而tomcat扮演的角色,涉及Servlet知识点,tomcat即Servlet容器。本文重点描述本人对Servlet内容的学习与理解。
(1) HttpServlet类图
以上类图中的各个接口、抽象类为tomcat自带的java.javax.servlet包中的接口、类;包含HttpServletRequest、HttpServletResponse两个接口也在该jar包内
(2) Servlet实际业务代码
一般情况下,我们会自定义一个继承HttpServlet类的一般的Servlet类,且在该类中重新override doGet()或者doPost()等方法,以完成响应。而HttpServlet源码中可得知,重写的doGet()或者doPost()方法是被service()方法调用的。那么,这里出现了一个断层,即:那么又是谁通过调用service()方法,继而简洁运行了doGet()或者doPost()方法呢?这就需要引入Servlet的生命周期。
(3) Servlet生命周期
在servlet编写过程中,我们可以知道servlet是需要首先在web.xml中配置好,才能根据配置的url-pattern进入对应配置好的servlet-class,这正是一个servlet的入口端。那么,针对当前进入的servlet-class, 程序是否在每次请求对应的url-pattern是都会进入并创建对应的Servlet类对象呢?这个答案是否定的,因为Servlet是单实例多线程的。即,该Servlet类实例只被创建一次,而这一个实例被多次调用。Servlet生命周期包含:创建对象,初始化对象,调用服务,销毁对象;
1) 创建对象
在web.xml配置servlet时,可以配置<load-on-startup>1</load-on-startup>;
当配置的值大于等于0时,对应的servlet在项目启动时创建并初始化对象;值越小越早被创建;
当配置的值小于0,或者不配置时,对应的servlet在第一次被请求时创建对象并初始化。
2) 初始化对象
在GerericServlet抽象类中包含两个初始化方法,一个有参init(ServletConfig config),一个无参init();
有参init(ServletConfig config)是实际tomcat调用的初始化方法,而无参init()是sun公司专门预留出来,用于给开发者重写自定义的初始化逻辑。由init(ServletConfig config)源码可知,tomcat调用该方法初始化时,也会调用被重写的init();源码如下:
public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); }
3) 调用服务
HttpServlet中的service方法是在服务器启动后,每次浏览器响应都会调用的方法。HttpServlet中包含两个参数类型不同的service方法:service(ServletRequest req, ServletResponse res),service(HttpServletRequest req, HttpServletResponse resp);前者会将输入参数类型强制转换为HttpServletRequest, HttpServletResponse类型,然后再在方法内部调用后者;而后者内,通过输入参数req的请求方式来判定调用doGet() 还是doPost()等相关方法;而doGet() 、doPost()等方法真是我们日常servlet中重写的业务逻辑
4) 销毁对象
tomcat服务器暂停或退出的时候,tomcat会调用GenericServlet中的destroy(),销毁Servlet对象。关于容器如何销毁对象,依然未知。destroy()方法中的内容为空,该方法可以被重写,即开发人员可以在容器调用该方法的时候,同时添加一些自己需要添加的业务操作。
(3) Servlet中4个核心对象
HttpServletRequest, HttpServletResponse, ServletConfig, ServletContext
此文不做细说明,可自行查阅api;