Http协议&Servlet
-
http协议
针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范。 其实就是规定了客户端在访问服务器端的时候,要带上哪些东西, 服务器端返回数据的时候,也要带上什么东西。
-
版本
1.0
请求数据,服务器返回后, 将会断开连接
1.1
请求数据,服务器返回后, 连接还会保持着。 除非服务器 | 客户端 关掉。 有一定的时间限制,如果都空着这个连接,那么后面会自己断掉。
Http请求数据解释
请求的数据里面包含三个部分内容 : 请求行 、 请求头 、请求体
-
请求行
POST /examples/servlets/servlet/RequestParamExample HTTP/1.1
POST : 请求方式 ,以post去提交数据
/examples/servlets/servlet/RequestParamExample
请求的地址路径 , 就是要访问哪个地方。
HTTP/1.1 协议版本 -
请求头
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, / Referer: http://localhost:8080/examples/servlets/servlet/RequestParamExample Accept-Language: zh-CN User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E) Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Host: localhost:8080 Content-Length: 31 Connection: Keep-Alive Cache-Control: no-cache
Accept: 客户端向服务器端表示,我能支持什么类型的数据。
Referer : 真正请求的地址路径,全路径
Accept-Language: 支持语言格式
User-Agent: 用户代理 向服务器表明,当前来访的客户端信息。
Content-Type: 提交的数据类型。经过urlencoding编码的form表单的数据
Accept-Encoding: gzip, deflate : 压缩算法 。
Host : 主机地址
Content-Length: 数据长度
Connection : Keep-Alive 保持连接
Cache-Control : 对缓存的操作 -
请求体
浏览器真正发送给服务器的数据
发送的数据呈现的是key=value ,如果存在多个数据,那么使用 &
firstname=zhang&lastname=sansan
Http响应数据解析
请求的数据里面包含三个部分内容 : 响应行 、 响应头 、响应体
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 673
Date: Fri, 17 Feb 2017 02:53:02 GMT
...这里还有很多数据...
-
响应行
HTTP/1.1 200 OK
协议版本
状态码
咱们这次交互到底是什么样结果的一个code.
200 : 成功,正常处理,得到数据。
403 : for bidden 拒绝
404 : Not Found
500 : 服务器异常
OK
对应前面的状态码 -
响应头
Server: 服务器是哪一种类型。 Tomcat
Content-Type : 服务器返回给客户端你的内容类型
Content-Length : 返回的数据长度
Date : 通讯的日期,响应的时间
Get 和Post请求区别
-
-
数据是以流的方式写过去,不会在地址栏上面显示。 现在一般提交数据到服务器使用的都是POST
-
以流的方式写数据,所以数据没有大小限制。
-
-
-
get
-
会在地址栏后面拼接数据,所以有安全隐患。 一般从服务器获取数据,并且客户端也不用提交上面数据的时候,可以使用GET
-
能够带的数据有限, 1kb大小
-
-
Web资源
在http协议当中,规定了请求和响应双方, 客户端和服务器端。与web相关的资源。
有两种分类
-
静态资源
-
动态资源
servlet/jsp
Servlet
-
servlet是什么?
其实就是一个java程序,运行在我们的web服务器上,用于接收和响应 客户端的http请求。
更多的是配合动态资源来做。 当然静态资源也需要使用到servlet,只不过是Tomcat里面已经定义好了一个 DefaultServlet
Hello Servlet
-
得写一个Web工程 , 要有一个服务器。
-
测试运行Web工程
-
新建一个类, 实现Servlet接口
-
配置Servlet , 用意: 告诉服务器,我们的应用有这么些个servlet。
在webContent/WEB-INF/web.xml里面写上以下内容。
-
-
<!-- 向tomcat报告, 我这个应用里面有这个servlet, 名字叫做HelloServlet , 具体的路径是com.itheima.servlet.HelloServlet -->
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.itheima.servlet.HelloServlet</servlet-class>
</servlet>
<!-- 注册servlet的映射。 servletName : 找到上面注册的具体servlet, url-pattern: 在地址栏上的path 一定要以/打头 -->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/a</url-pattern>
</servlet-mapping>
3. 在地址栏上输入 http://localhost:8080/项目名称/a
Servlet执行过程
Servlet的通用写法
Servlet (接口)
|
|
GenericServlet
|
|
HttpServlet (用于处理http的请求)
-
定义一个类,继承HttpServlet 复写doGet 和 doPost
Servlet的生命周期
-
生命周期
从创建到销毁的一段时间
-
生命周期方法
从创建到销毁,所调用的那些方法。
-
init方法
在创建该servlet的实例时,就执行该方法。 一个servlet只会初始化一次, init方法只会执行一次 默认情况下是 : 初次访问该servlet,才会创建实例。
-
service方法
只要客户端来了一个请求,那么就执行这个方法了。 该方法可以被执行很多次。 一次请求,对应一次service方法的调用
-
destroy方法
servlet销毁的时候,就会执行该方法
1. 该项目从tomcat的里面移除。
2. 正常关闭tomcat就会执行 shutdown.bat
doGet 和 doPost不算生命周期方法,所谓的生命周期方法是指,从对象的创建到销毁一定会执行的方法, 但是这两个方法,不一定会执行。
ServletConfig接口简介
在 Servlet 接口的 init()方法中有一个参数 ServletConfig,这个参数类型是个接口,里面是一些 在 web.xml 中对当前 Servlet类的配置信息。Servlet 规范将Servlet 的配置信息全部封装到了 ServletConfig 接口对象中。在tomcat调用 init()方法时,首先会将 web.xml 中当前 Servlet 类的配置信息封装为一个对象。这个对象的类型实现了 ServletConfig 接口, Web 容器会将这个对象传递给init()方法中的 ServletConfig 参数。
ServletConfig中的方法
- getInitParameter(): 获取指定名称的初始化参数值。例如从下面的servlet中调用 getInitParameter("userName");方法会返回字符串"monkey1024"。
- getInitParameterNames():获取当前 Servlet 所有的初始化参数名称。其返回值为枚举类型 Enumeration。
- getServletName():获取当前 Servlet 的中指定的 Servlet名称。如下面中的 ServletName 为"configServlet"。
- getServletContext():获取到当前 Servlet 的上下文对象 ServletContext,这是个非常重要的对象,将在下一节中详细介绍。
在配置web.xml时,可以为servlet指定多个初始化参数:
1 <servlet> 2 <servlet-name>configServlet01</servlet-name> 3 <servlet-class>com.monkey1024.servlet.ConfigTest01</servlet-class> 4 <init-param> 5 <param-name>userName</param-name> 6 <param-value>monkey1024</param-value> 7 </init-param> 8 <init-param> 9 <param-name>password</param-name> 10 <param-value>123456</param-value> 11 </init-param> 12 </servlet> 13 <servlet-mapping> 14 <servlet-name>configServlet01</servlet-name> 15 <url-pattern>/config01</url-pattern> 16 </servlet-mapping>
创建一个servlet:
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 import java.util.Enumeration; 5 6 import javax.servlet.Servlet; 7 import javax.servlet.ServletConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 12 /** 13 * ServletConfig接口 14 * 15 */ 16 public class ConfigTest01 implements Servlet { 17 18 private ServletConfig config; 19 20 @Override 21 public void destroy() { 22 23 } 24 25 @Override 26 public ServletConfig getServletConfig() { 27 return this.config; 28 } 29 30 @Override 31 public String getServletInfo() { 32 return null; 33 } 34 35 @Override 36 public void init(ServletConfig servletConfig) throws ServletException { 37 System.out.println("init方法中ServletConfig:" + servletConfig); 38 this.config = servletConfig; 39 } 40 41 @Override 42 public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { 43 String userName = config.getInitParameter("userName"); 44 System.out.println("userName=" + userName); 45 Enumeration<String> param = config.getInitParameterNames(); 46 47 while(param.hasMoreElements()){ 48 String name = param.nextElement(); 49 String value = config.getInitParameter(name); 50 System.out.println(name + "=" + value); 51 } 52 53 System.out.println("ServletName=" + config.getServletName()); 54 55 } 56 57 }
ServletConfig的特点
每一个servlet都对应一个ServletConfig用于封装各自的配置信息,即有几个servlet就会产生几个ServletConfig对象。
为什么需要有这个ServletConfig
-
未来我们自己开发的一些应用,使用到了一些技术,或者一些代码,我们不会。 但是有人写出来了。它的代码放置在了自己的servlet类里面。
-
刚好这个servlet 里面需要一个数字或者叫做变量值。 但是这个值不能是固定了。 所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声明init-params
在开发当中比较少用。
ServletContext接口简介
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,ServletContext对象包含Web应用中所有 Servlet 在 Web 容器中的一些数据信息。ServletContext随着Web应用的启动而创建,随着 Web 应用的关闭而销毁。一个 Web 应用只有一个ServletContext 对象。
ServletContext中不仅包含了 web.xml 文件中的配置信息,还包含了当前应用中所有Servlet可以共享的数据。可以这么说, ServeltContext 可以代表整个应用,所以ServletContext有另外一个名称:application。
ServletContext中常用方法
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext()方法获得ServletContext对象。
- String getInitParameter ():获取 web.xml 文 件 的 中 指 定 名 称 的上下文参数值 。
- Enumeration getInitParameterNames():获取 web.xml 文件的中的所有的上下文参数名称。其返回值为枚举类型 Enumeration。
- void setAttribute(String name, Object object):在 ServletContext 的公共数据空间中,也称为域属性空间,放入数据。这些数据对于 Web应用来说,是全局性的,与整个应用的生命周期相同。当然,放入其中的数据是有名称的,通过名称来访问该数据。
- Object getAttribute(String name):从 ServletContext 的域属性空间中获取指定名称的数据。
- void removeAttribute(String name):从 ServletContext 的域属性空间中删除指定名称的数据。
- String getRealPath(String path):获取当前 Web 应用中指定文件或目录在本地文件系统中的路径。
- String getContextPath():获取当前应用在 Web 容器中的名称。
示例:
在web.xml文件中加入初始化参数,web.xml文件修改后要重启tomcat才能生效:
<!-- 初始化参数 -->
<context-param>
<param-name>MySQLDriver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
<param-name>dbURL</param-name>
<param-value>jdbc:mysql:</param-value>
</context-param>
创建servlet:
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.Servlet; 6 import javax.servlet.ServletConfig; 7 import javax.servlet.ServletContext; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 12 /** 13 * ServletContext接口 14 * 15 */ 16 public class ContextTest01 implements Servlet { 17 18 private ServletConfig config; 19 20 @Override 21 public void destroy() { 22 23 } 24 25 @Override 26 public ServletConfig getServletConfig() { 27 return this.config; 28 } 29 30 @Override 31 public String getServletInfo() { 32 return null; 33 } 34 35 @Override 36 public void init(ServletConfig servletConfig) throws ServletException { 37 this.config = servletConfig; 38 } 39 40 @Override 41 public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { 42 ServletContext application = this.config.getServletContext(); 43 System.out.println("ContextTest01:" + application); 44 45 String driver = application.getInitParameter("MySQLDriver"); 46 System.out.println(driver); 47 48 String contextPath = application.getContextPath(); 49 System.out.println("contextPath:" + contextPath); 50 51 //文件在硬盘中的绝对路径 52 String realPath = application.getRealPath("FirstServlet"); 53 System.out.println("realPath:" + realPath); 54 55 //向ServletContext中添加属性 56 application.setAttribute("admin", "tiger"); 57 application.setAttribute("password", 123456); 58 //删除password 59 application.removeAttribute("password"); 60 } 61 62 }
再创建一个servlet:
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.Servlet; 6 import javax.servlet.ServletConfig; 7 import javax.servlet.ServletContext; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 12 public class ContextTest02 implements Servlet { 13 14 private ServletConfig config; 15 16 @Override 17 public void init(ServletConfig config) throws ServletException { 18 this.config = config; 19 } 20 21 @Override 22 public ServletConfig getServletConfig() { 23 // TODO Auto-generated method stub 24 return null; 25 } 26 27 @Override 28 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 29 ServletContext application = this.config.getServletContext(); 30 System.out.println("Context02中的application:" + application); 31 32 33 String admin = (String)application.getAttribute("admin"); 34 System.out.println(admin); 35 String password = (String)application.getAttribute("password"); 36 System.out.println(password); 37 } 38 39 @Override 40 public String getServletInfo() { 41 // TODO Auto-generated method stub 42 return null; 43 } 44 45 @Override 46 public void destroy() { 47 // TODO Auto-generated method stub 48 49 } 50 51 }
-
Http协议
-
使用HttpWacht 抓包看一看http请求背后的细节。
-
基本了解 请求和响应的数据内容
请求行、 请求头 、请求体 响应行、响应头、响应体
-
Get和Post的区别
-
-
-
Servlet【重点】
-
会使用简单的servlet
1.写一个类,实现接口Servlet
-
配置Servlet
-
会访问Setvlet
-
-
Servlet的生命周期
init 一次 创建对象 默认初次访问就会调用或者可以通过配置,让它提前 load-on-startup service 多次,一次请求对应一次service destory 一次 销毁的时候 从服务器移除 或者 正常关闭服务器
-
ServletConfig
获取配置的信息, params
-
-
- 项目部署后启动服务器,并没有执行 Servlet 的无参构造器方法,说明在 Web 容器启动时并没有创建 Servlet 对象。
- 用户提交请求URL后,马上可以看到无参构造方法、init()方法、service()方法均执行。
- 刷新页面,发现只会执行 service()方法,每刷新一次,即每提交一次请求,就会执行一次 service()方法。
- 让另外一个浏览器也发出同样的请求,会发现只执行 service()方法,而无参构造方法、 init()
方法均未执行。 - 正常关闭 Tomcat(使用 stop server 关闭,不能使用 Terminate 关闭),发现 destroy()方
法也会执行。
servlet的特征
- Servlet是单例多线程的,只创建一个servlet对象,但是每次请求都会起一个线程并在自己线程栈内存中执行service方法。
- 一个 Servlet 实例只会执行一次无参构造器与 init()方法,并且是在第一次访问时执行。
- 用户每提交一次对当前 Servlet 的请求,就会执行一次 service()方法。
- 一个 Servlet 实例只会执行一次 destroy()方法,在应用停止时执行。
- 由于 Servlet 是单例多线程的,所以为了保证其线程安全性,一般情况下是不建议在 Servlet类中定义可修改的成员变量,因为每个线程均可修改这个成员变量,会出现线程安全问题。
- 默认情况下,Servlet 在 Web 容器启动时是不会被实例化的。
tomcat启动时创建servlet实例
在tomcat启动时,默认不会创建servlet实例,如果想要让tomcat在启动时创建servlet实例的话,只需要在web.xml中添加load-on-startup标签即可
1 <servlet> 2 <servlet-name>lifeServlet</servlet-name> 3 <servlet-class>com.monkey1024.servlet.LifeServlet</servlet-class> 4 <load-on-startup>1</load-on-startup> 5 </servlet> 6 <servlet-mapping> 7 <servlet-name>lifeServlet</servlet-name> 8 <url-pattern>/life</url-pattern> 9 </servlet-mapping>
添加load-on-startup的作用是,标记是否在 Tomcat启动时创建并初始化这个 Servlet实例。它的值必须是一个整数。
- 当值大于等于 0 时,表示容器在启动时就加载并初始化这个 Servlet,数值越小,该 Servlet的优先级就越高,其被创建的也就越早;
- 当值相同时,容器会自己选择创建顺序。
设置欢迎页面
在浏览器地址栏中直接通过项目名称访问时,默认显示的页面就是欢迎页面,可以是.html.jsp,可以通过welcome-file-list进行设置。
设置多个欢迎页面:
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list>
可以为应用设置多个欢迎页面,但只会有一个起作用,系统加载这些欢迎页面的顺序与
其代码的顺序相同,即由上到下逐个查找,一旦找到,则马上显示,不会再向下查找。
如果当前应用没有指定欢迎页面,则系统会从当前项目的根目录下依次查找 index.html、 index.htm
及 index.jsp 文件,如果这些文件不存在的话,浏览器会报出 404 错误。
url-pattern的设置
url-pattern标签用于对请求进行筛选匹配,对当前注册的 Servlet 所要处理的请求类
型进行筛选。对于url-pattern中路径的写法,有多种不同模式,表示不同的意义,一个Servlet可以对应多个url-pattern.
精确路径模式
请求路径必须与url-pattern的值完全相同才可被当前 Servlet 处理。
1 <servlet-mapping> 2 <servlet-name>contextServlet02</servlet-name> 3 <url-pattern>/context02</url-pattern> 4 <url-pattern>/servlet/context02</url-pattern> 5 <url-pattern>/test/servlet/context02</url-pattern> 6 </servlet-mapping>
通配符路径模式
该模式中的路径由两部分组成:精确路径部分与通配符部分。请求路径中只有携带了url-pattern值中指定的精确路径部分才可被当前 Servlet 处理。
1 <servlet-mapping> 2 <servlet-name>contextServlet02</servlet-name> 3 <url-pattern>/servlet/*</url-pattern> 4 </servlet-mapping>
全路径模式
提交的所有请求全部可被当前的 Servlet 处理。其值可以指定为/*,也可指定为/。
1 <servlet-mapping> 2 <servlet-name>contextServlet02</servlet-name> 3 <url-pattern>/*</url-pattern> 4 </servlet-mapping>
或
1 <servlet-mapping> 2 <servlet-name>contextServlet02</servlet-name> 3 <url-pattern>/</url-pattern> 4 </servlet-mapping>
/*与/表示所有请求均会被当前 Servlet 所处理。如果一个servlet的url-pattern是/*或/,则该servlet表示默认映射,当一个请求找不到相应的url的servlet时,系统会调用这个默认映射的servlet。
这两个路径的不同之处是:
-
使用/*,表示当前的 Servlet 会拦截用户对于静态资源(.css、.js、.html、.jpg、.png…..)
与动态资源(.jsp)的请求。即用户不会直接获取到这些资源文件,而是将请求交给当前 Servlet
来处理了。 -
使用/,表示当前的 Servlet 会拦截用户对于静态资源(.css、.js、.html、.jpg、.png…..),
但对于动态资源的请求,是不进行拦截的。即用户请求的静态资源文件是不能直接获取到的。
综上所述,对于 Servlet 的url-pattern的设置,我们一般是不会将其指定为/*或/的。
一旦有一个 Servlet 的url-patter被设置为了/*或/,则整个应用的静态资源将可能无法正常显示。
后辍名模式
请求路径最后的资源名称必须携带中指定的后辍名,其请求才可被当前Servlet 处理
1 <servlet-mapping> 2 <servlet-name>contextServlet02</servlet-name> 3 <url-pattern>*.do</url-pattern> 4 </servlet-mapping>
url-pattern路径优先级
路径优先后辍匹配原则
例如 SomeServlet的url-pattern为*.do,OtherServlet 的url-pattern
为 /xxx/*。若用户提交的请求 URL 为 http://localhost:8080/oa/xxx/abc.do
,此时服务器发现 SomeServlet 的*.do 与 OtherServlet 的/xxx/*都可以与用户提交请求的
/xxx/abc.do 相匹配。那么服务器会按照“路径优先后辍匹配”的原则选择 OtherServlet。
精确路径优先匹配原则
例如 SomeServlet的url-pattern为/some, OtherServlet 的url-pattern
为 /*。若用户提交的请求 URL 为 http://localhost:8080/oa/some
,此时服务器发现SomeServlet 的/some 与 OtherServlet 的/*都可以与用户提交请求的/some 相匹配。那么服务器会按照“精确路径优先匹配”的原则选择 SomeServlet。
最长路径优先匹配原则
例如 SomeServlet 的url-pattern为/some/*,OtherServlet 的
url-pattern为 /some/other/*。若用户提交的请求 URL 为
http://localhost:8080/oa/some/other
,此时服务器发现 SomeServlet 的/some/*
与 OtherServlet 的/some/other/*都可以与用户提交请求的/some/other 相匹配。那么
服务器会按照“最长路径优先匹配”的原则选择 OtherServlet。
继承GenericServlet类
在通过实现Servlet接口来定义一个Servlet类时存在一个很不方便的问题:有太多不需要的方法必须要实现。通常我们只在service()方法中完成业务逻辑,但由于Servlet 接口中还存在另外四个方法,所以也要必须实现。
为了解决这个问题JavaEE的API中提供了一个javax.servet.GenericServlet类,开发者在定义一个servlet时继承该GenericServlet类,此时只需要重写service方法即可。
适配器模式
什么是适配器模式:
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
可以将这里的适配器看做是一个万能充电接口,该充电接口一端可以连接安卓手机的充电器,另一端连接苹果手机,这样就实现了使用安卓手机的充电器给苹果手机充电了。
继承HttpServlet类
在实际应用中常用的http提交方式有get和post(除此之外还有put、delete),在之前所编写的servlet中是无法直接处理这两种提交方式的,为了方便开发,JavaEE规范的API提供了javax.servlet.http.HttpServlet类,在实际开发中也经常使用继承HttpServlet类的方式创建一个servlet。
1 package com.monkey1024.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 /** 11 * 继承HttpServlet处理get和post请求 12 * 13 */ 14 public class HttpTest01 extends HttpServlet { 15 16 @Override 17 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 18 System.out.println("执行doGet方法"); 19 } 20 21 @Override 22 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 23 System.out.println("执行doPost方法"); 24 } 25 26 27 }
上面是通过继承HttpServlet来创建的一个名为HttpTest01的servlet,在HttpTest01中并没有重写service方法,主要重写了doGet和doPost方法来分别处理http请求中的get和post,除此之外,在HttpServlet类中还有doPut、doDelete等其他用于处理http请求的方法。
快速创建Servlet
在eclipse中右键—>new—>servlet可以快速创建一个Servlet,该Servlet会默认继承HttpServlet类并重写doGet和doPost方法,并且在创建的过程中可以帮我们生成web.xml相关servlet标签配置,这样就不用手动编写了。
模板方法设计模式
什么是模板方法设计模式
定义一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
比如考试的时候,学生是共用同一套试卷,只是学生各自的答案是不同的;因此,试题题目是模板方法是不变的,而试题答案对于每个学生是可变的。
Servlet(爷爷) –> GenericServlet(爸爸) –> HttpServlet(儿子)
Servlet相关类总结
上图中描述了servlet中常用的接口和类之间的关系,图中下面三个类和接口都是在javax.servlet.http包下,上面的类和接口都在javax.servlet包下。
如果是通过参数传过来的对象,就叫依赖
通过方法得到的对象,就叫关联
- 上图中tomcat通过Servlet接口中的init方法将ServletConfig对象传递过去,所以Servlet接口依赖ServletConfig接口。
- Servlet接口中通过调用getServletConfig方法可以获取ServletConfig对象,所以Servlet接口也关联ServletConfig接口。
- 在ServletConfig接口中通过getServletContext方法获取ServletContext对象,所以ServletConfig接口关联ServletContext接口。
- GenericServlet类分别实现了Servlet接口和ServletConfig接口
- HttpServlet类继承了GenericServlet类
- HttpServletRequest接口继承ServletRequest接口
- HttpServletResponse接口继承ServletResponse接口