现在很多的开发都是用的框架,然后很多同学学习的时候又是直接接触的框架,对于底层的一些开发,完全没有任何的了解。虽然对于业务上面来说,没有什么问题。但是很多时候当你被面试问到,或者是想要了解框架底层原理的时候,这就不得不知道了。所以今天详细说说它。

开发servlet的三种方式

1、实现servlet接口(偏向底层)

2、继承GenericServlet(觉得1不好用,就开发了这个,现在基本没啥用)

3、继承HttpServlet(现在大多数用这个)

理解实现servlet接口的方式,理解servlet生命周期

首先当servlet第一次被调用的时候,会调用servlet的init方法,把servlet实例装载到内存中。

之后会调用service方法,当第二次servlet被访问的时候就会直接调用service函数。

只有当web应用关闭,或者容器关闭,或者电脑关闭时候,才会调用destroy方法销毁servlet

下面是浏览器发出请求后servlet执行的流程图

Servlet接口有五个方法

init初始化,就是把servlet装载到内存中,只会被调用一次

getServletConfig获取servletConfig对象

service主要的服务方法,放业务逻辑,每次都会被调用

getServletInfo得到servlet配置信息

destroy销毁该servlet,从内存中清除掉

继承GenericServlet

GenericServlet实现了servlet接口

然后只有一个抽象方法需要你自己去重写

那就是service方法,所以相比来说init别的方法他都帮你实现好了,只要你写service方法就可以了。

至少看起来继承GenericServlet比直接实现servlet接口要方便

这个类是在javax.servlet.GenericServlet下的

继承HttpServlet

因为后来发现servlet主要是为了服务于http请求的,而且发现GenericServlet对于http来说还不够好

所以有了HttpServlet,首先它是继承自GenericServlet

然后它有很多http相关的方法,post,get,put等待

用户可以根据自己需要来实现这些方法

每个过来的请求都会调用service方法,最后service会根据不用的请求分发到不同的地方去做。

下面的问题中会在源码中详细说明。

下面有关servlet service描述错误的是?

1、不管是post还是get方法提交过来的连接,都会在service中处理

每次请求都会调用service方法,最终都会在service中处理,正确;

2、doGet/doPost 则是在 javax.servlet.GenericServlet 中实现的

GenericServlet只是继承了Servlet的接口,实现了它其中的5个方法,其中需要用户重写的是service方法,而doGet/doPost是因为之后出现了HttpServlet才有的,是针对http请求才有了这个类,才有了doPost和doGet,所以是错误的。

3、service()是在javax.servlet.Servlet接口中定义的

Servlet接口一共定义了5个方法,其中就有service(),正确;

4、service判断请求类型,决定是调用doGet还是doPost方法

下面详细说说最后一个选项。

我们来看一看源码

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 = req.getDateHeader(HEADER_IFMODSINCE);
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);
}
} } else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp); } else if (method.equals(METHOD_POST)) {
doPost(req, resp); } else if (method.equals(METHOD_PUT)) {
doPut(req, resp); } else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp); } else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
// String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
 

这个就是HttpServlet中service方法的源码

首先我们看到的就是String method = req.getMethod();

这个就是通过request获取方法

然后根据方法判断调用哪一个方法

要说明的是前面它已经定义好了那些字符串

private static final String METHOD_DELETE = "DELETE"; 
   private static final String METHOD_HEAD = "HEAD"; 
   private static final String METHOD_GET = "GET"; 
   private static final String METHOD_OPTIONS = "OPTIONS"; 
   private static final String METHOD_POST = "POST"; 
   private static final String METHOD_PUT = "PUT"; 
   private static final String METHOD_TRACE = "TRACE"; 
所以第四个选项说:service判断请求类型,决定是调用doGet还是doPost方法,是正确的。

需要指出的是

前面说过

HttpServlet是继承自GenericServlet,而GenericServlet需要用户实现一个service,刚才我们看到的是它自己的

而在HttpServlet中其实是有的。它肯定要写这样一个方法的。

public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response; try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
 

源码是这样的,它会把原来的ServletRequest 请求直接强转换成HttpServletRequest然后再去调用它正真的service方法。

这点是需要指出的,HttpServletRequest比ServletRequest进行了进一步的封装,方法更适合http。

Servlet的生命周期分为5个阶段:加载、创建、初始化、处理客户请求、卸载。
(1)加载:容器通过类加载器使用servlet类对应的文件加载servlet
(2)创建:通过调用servlet构造函数创建一个servlet对象
(3)初始化:调用init方法初始化
(4)处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求
(5)卸载:调用destroy方法让servlet自己释放其占用的资源
 

详细理解servlet实现的三种方式和生命周期的更多相关文章

  1. 详细理解servlet实现的几种方式和生命周期

    现在很多的开发都是用的框架,然后很多同学学习的时候又是直接接触的框架,对于底层的一些开发,完全没有任何的了解.虽然对于业务上面来说,没有什么问题.但是很多时候当你被面试问到,或者是想要了解框架底层原理 ...

  2. Servlet实现的三种方式

    实现Servlet的三种方式:一个实现,两个继承 /*========================================== * servlet的执行过程: * 1.创建servlet对 ...

  3. Struts2访问Servlet API的三种方式

    有时我们需要用到Request, Response, Session,Page, ServletContext这些我们以前常用的对象,那么在Struts2中怎么样使用到这些对象呢,通常有三种方式. * ...

  4. servlet实现的三种方式对比(servlet 和GenericServlet和HttpServlet)

    第一种: 实现Servlet 接口 第二种: 继承GenericServlet 第三种 继承HttpServlet (开发中使用) 通过查看api文档发现他们三个(servlet 和GenericSe ...

  5. Hibernate三种状态及生命周期

    临时状态---使用new操作符的对象不能立刻持久,也就是说没有任何跟数据库相关的行为, 只要应用不再使用这些对象,状态会丢失,并由垃圾回收机制回收持久对象---持久实例是具有数据库标识的实例.统一又S ...

  6. java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))

    1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...

  7. 创建servlet的三种方式

    第一种方式,实现Servlet接口 package com.example.servlet; import java.io.IOException; import javax.servlet.Serv ...

  8. SpringBoot学习笔记(6)----SpringBoot中使用Servlet,Filter,Listener的三种方式

    在一般的运用开发中Controller已经大部分都能够实现了,但是也不排除需要自己实现Servlet,Filter,Listener的方式,SpringBoot提供了三种实现方式. 1. 使用Bean ...

  9. WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式

    原文:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式 由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件.这篇文章介绍在WPF中实现PropertyGr ...

随机推荐

  1. CAN调度理论与实践分析

    CAN调度理论与实践分析 分布式嵌入式系统是当前嵌入式系统的重要发展方向,因为它能提供更强的性能,节约系统的总体成本.但是由于各单个节点必须有通信网络相连才能协调地工作,网络就成了关键部分,没有网络提 ...

  2. 笔记:载入viewcontroller的几种方式

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; ...

  3. OO——电梯作业总结

    目录 电梯作业总结 程序结构与复杂度的分析 第一次作业 第二次作业 第三次作业 程序BUG的分析 互测 自动评测 有效性 总结 电梯作业总结 程序结构与复杂度的分析 第一次作业 1.设计思路 第一次作 ...

  4. Vivado中xilinx_courdic IP核(求exp指数函数)使用

    由于Verilog/Vhdl没有计算exp指数函数的库函数,所以在开发过程中可利用cordic IP核做exp函数即e^x值: 但前提要保证输入范围在(-pi/4—pi/4) 在cordic核中e^x ...

  5. 2017-2018-2 20155230《网络对抗技术》实验8:Web基础

    实践过程记录 1.Web前端HTML 首先用指令sudo apt-get install apache2下载apache,由于实验机已经安装好Apache,这里就不演示了,对于Apache使用的端口我 ...

  6. 20155323刘威良《网络对抗》Exp4 恶意代码分析

    20155323刘威良<网络对抗>Exp4 恶意代码分析 实践目标 1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件: ...

  7. Java中枚举的写法和用法

            在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法         关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...

  8. 2017战略No.2:开始电子化记账

    一.懒散的4年 大学毕业后,就没有怎么记账了. 自己花的钱,心里有个大概,但是不能算得很具体. 比如说,2016年,又没有攒几个钱,心里多少有点压抑. 大脑去算账,只能算房租吃饭等金额较大的开销,更多 ...

  9. 如何完全卸载VS2010(亲自体验过) (转)

    1.首先用360卸载,当卸载完成后,提示有残余的话,就强力清除 2,接着,下载IobitUninstaller工具 3.按照下面进行卸载 1.Microsoft .NET Framework 4 框架 ...

  10. flask_admin 笔记三 客户化视图

    客户化视图1, model数据模型参数配置1)配置全局参数内置的ModelView类很适合快速入门. 但是,您需要配置其功能以适合您的特定型号. 这是通过设置ModelView类中提供的配置属性的值来 ...