Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
-
Servlet 初始化后调用 init () 方法。
-
Servlet 调用 service() 方法来处理客户端的请求。
-
Servlet 销毁前调用 destroy() 方法。
-
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
执行原理步骤:
-
Web Client 向Servlet容器(Tomcat)发出Http请求
-
Servlet容器接收Web Client的请求
-
Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
-
Servlet容器创建一个HttpResponse对象
-
Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet 对象。
-
HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
-
HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
-
Servlet容器把HttpServlet的响应结果传给Web Client。
原理:
-
首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet()、doPost()等等这些方法的,HttpServlet中定义了这些方法,但是都是返回error信息,所以,我们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。
-
每一个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。
-
Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,所以HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。
-
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
init 方法的定义如下:
public void init() throws ServletException {
// 初始化代码...
}
service() 方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
利用service()方法代替doGet()方法和doPost()方法,反射。
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String method=req.getParameter("method");
try {
this.getClass().getDeclaredMethod(method,HttpServletRequest.class,HttpServletResponse.class).invoke(this,req,resp);
}catch (Exception e){
e.printStackTrace();
}
}
service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。
doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征
doGet() 方法 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
doPost() 方法
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
destroy() 方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收,即销毁方法。
public void destroy() {
// 终止化代码...
}
过滤器(Filter)的简介
过滤器的作用: 过滤器可以对所有的请求或者响应做拦截操作.
1:以常规的方式调用资源(Servlet/JSP);
2:利用修改过的请求信息调用资源;
3:调用资源之后,但在响应到客户端之前,对响应做出修改;
4:阻止当前资源调用,代之转到其他资源.
Filter的开发和使用1:自定义一个类(XxxFilter,Xxx表示功能名),实现于javax.servlet.Filter接口.
2:在wed.xml里面配置拦截器
Filter的生命周期方法XxxFilter XxxFilter类的全限定名 XxxFilter /hello.jsp
void init(FilterConfig config): 初始化方法 (2):void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):执行过滤的方法(每一次请求都会执行过滤) (3):void destroy():销毁方法 执行的流程: 在启动Tomcat服务器的时候,就会执行构造器和init方法. 构造器--->init方法 -----> ( doFilter方法 )N次------->destroy方法
-
具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
-
拦截目录: /user
@Override
public void contextInitialized(ServletContextEvent sce) {System.out.println("ServletContext创建了");ServletContext application = sce.getServletContext();//整个应用程序只有一个对象
application.setAttribute("config","123");//设置初始化数据}
@Override
public void contextDestroyed(ServletContextEvent sce) {System.out.println("ServletContext销毁了");}
long s = 0;
@Override
public void requestInitialized(ServletRequestEvent sre) {System.out.println("请求对象创建");s = System.currentTimeMillis();
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {System.out.println("请求对象销毁");//获取客户端ip
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
System.out.println(request.getRemoteAddr()+"请求耗时:::"+(System.currentTimeMillis()-s));
}



