JavaWeb开发之Servlet(二)

xiaoxiao2021-02-28  108

基于上次的Servlet详解,描述了Servlet对象在应用中的生命周期,以及基本的XML文件配置,使得Tomcat容器去管理Servlet对象 . 在本块详解中,对Servlet类的继承体系进行详细描述.

这里呢我就用很简单的画一张继承体系图 GenericServlet是一个抽象类,可以处理普通的请求和响应,必须给出子类才可以进行实例化.它给出了设计Servlet的骨架和定义.提供了得到配置,初始化参数等方法.而HttpServlet则是它的实现子类,可以进行处理HTTP类型的请求和响应,在HttpServlet中添加了doGet,doPost,doDelete,doTrace等方法处理http协议中请求和响应. 只是一般我们都需要进行拓展HttpServlet所以需要进行重写.

package com._jerry._demo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/demo") //在Servlet3.0后,我们可以不再使用XML文件进行配置Servlet,而只有注解的形式进行解决,/demo是资源的路径,一般项目开发中我们省略资源的上下文路径,需要注意'/',资源前不能漏,否则会子启动Tomcat的时候即会报错. public class DemoServlet extends HttpServlet{ private static final long serialVersionUID = 1L; public DemoServlet() { System.out.println("调用构造器..."); // 提供一个构造器来演示方法调用的过程 } public void init() throws ServletException { System.out.println("初始化..."); /*这里需要注意的是在我们init方法其实是GenericServet方法暴露给HttpServet的方法: //这段示例代码来自GenericServlet类 public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { // NOOP by default } 这种方法叫做钩子方法,原因在于父类中的init方法是用来获取配置参数的,而子偶自己的逻辑实现,所以提供一个init方法个给子类,然后在父类init方法中将子类的新增方法进行调用. */ } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("service方法..."); } public void destroy() { // Servlet销毁的方法 System.out.println("销毁Servlet..."); } protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } //--------------------------------------------------------- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } //这里的二个方法是HttpServlet类中定义的,本文就在自定义Servlet中重写了,主要是为了观察.在HttpServlet类中的Service方法其实会在请求中去获取当前的请求方式,然后再去调用对应的doGet方法或者doPost方法,取决于当前的请求是Get还是Post,但是因为我们自身开发的时候没有特殊需求下,一般会覆盖父类中的service方法所以也就不去关注doGet和doPost了. //--------------------------------------------------------- } 为了看明白父类HttpServlet中service具体的代码,我们仔细看看 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) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid date header - proceed as if none was set ifModifiedSince = -1; } if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } } //其实以上也就是在做一个请求分发的操作,将对应的Get或者Post方法调用响应方法进行请求的处理.

Servlet类然后启动Tomcat服务器,在浏览器中访问已经配置好的这个Servlet资源,并进行测试 在控制台输出的结果为

调用构造器... 初始化... service方法... ---------- 再在浏览器中请求一次 显示如下: 调用构造器... 初始化... service方法... service方法...

从上面我们可以看出,在Tomcat启动后,我们在浏览器请求资源后,Tomcat先去管理Servlet,并且调用该Servlet的构造器进行实例化,然后和调用init方法进行参数初始化,最好调用service进行接收请求操作,再第二次的请求的时候,就只调service方法了,所以得知在每个Servlet对象的生命周期中,构造器和init方法只有在发起请求并访问该Servet资源的时候执行且只执行一次. 以上我们还可以注意到,Servlet中的destroy销毁方法并没有执行,其实这个一般是在Tomcat服务器关闭或者资源关闭的时候才会自己进行处理.

转载请注明原文地址: https://www.6miu.com/read-69777.html

最新回复(0)