Servlet来由_使用_详解

一、什么是Servlet

1.我们先聊一聊Servlet产生的原因

(1)动态、静态网页区分
网页有静态和动态之分。所谓的静态和动态区分的标准——不是指图片或文字的动态效果,而是指能否实现客户端与服务器端进行交互(交互指客户端给服务器发送请求,服务器能够做出应答,从而保证客户端网页的数据是可以更新的)。

(2)Servlet的产生
Servlet=Service+Applet,表示小服务程序。Servlet是运行在Web服务器或应用服务器上的程序。但是Servlet并不是服务于Web的唯一方式。满足该目的的最早的技术之一是公共网关接口(CGI)。CGI为每个请求派生不同的进程,因而影响效率。我们在此对比一下Servlet和CGI,在传统的CGI中,如果有N个并发对同一个CGI程序进行请求,则该CGI程序的代码在内存中重复状态N次;而对于Servlet而言,处理请求的方式是创建N个线程,只需要一份Servlet类代码,在性能优化方面,Servlet也比CGI有着更多的选择。

2.正题:什么是Servlet及访问Servlet的全过程

上文中我们说到动态网页是指能实现客户端与服务器进行交互的网页,但是如何进行交互呢?这个关键的交互问题,正是Servlet要解决的问题,下面我们来看一下全过程(简单了解即可)。

(1)浏览器从地址栏中获取主机名,并获取主机名对应的IP地址。
详细过程可去了解DNS解析过程,结果是最终会获取到要访问的IP地址。

(2)浏览器与Web服务器建立一个TCP连接。
HTTP是应用层协议,需要传输层的TCP为其提供一条可靠的比特传输管道,此过程不一定在HTTP请求之前,例如HTTP/1.0中TCP连接是在HTTP请求创建的时候同步创建的。
详细过程可去了解TCP连接的三次握手和四次挥手。
(3)浏览器向服务器(Tomcat)发送HTTP请求。
这个请求一般是GET请求或POST请求。请求指的是请求报文,请求报文由四个部分组成:请求行、请求头、空行、请求数据。此处我们只说请求报文中里对于本文章来说的重点,详细可去了解HTTP请求报文内容
请求行中包括:方法字段——请求方法(GET或POST等,HTTP/1.1协议中规定了8中方法)、URL字段和HTTP版本协议。
请求头中包含的内容有很多,包括:HOST——访问的主机名。
空行:告诉服务器请求头到此为止。
请求数据:
若方法字段是GET,则此项为空,没有数据,数据在以字符串的格式存放在URL中。如果数据是英文或数字,原样发送;若为空格,转化为+;若为中文/其他字符,则将字符串用BASE64加密。
若方法为POST,则通常来说,此处放置的就是要提交的数据。
(4)服务器读取请求报文中的内容,确定客户机要访问的主机名。
此过程着实复杂,且不是本文重点,简单概述一下,详情过程可去了解Tomcat源码之对HTTP报文解析,此过程牵扯到Tomcat的两个核心组件:Connector和Container。
Tomcat启动后,Connector组件在指定的端口上侦听客户请求,接收浏览器发过来的TCP连接。然后产生一个线程处理这个请求并把请求交给Service的Engine容器来处理,并等待回应,为方便理解,盗了张图为:Container的体系结构,Servlet即在Container中。

(5)服务器从请求消息中确定客户机要访问的具体WEB应用。
Engine获得请求(接收请求和相应的对象),匹配主机名,并将请求交给字容器Host处理。
(6)服务器从请求消息中确定客户机要具体访问的WEB资源。
Host获得请求,匹配他所拥有的所有Context(Context是由多个Servlet组成,在创建Context时,根据配置文件加载Servlet,并创建映射表mapping table),结果是匹配到了对应的Context。

(7)服务器发现客户机访问的是一个Servlet程序。
Context获得请求,在它的映射表(mapping table)中寻找对应的Servlet。如果找到,则执行,获得请求的回应,并返回。如果没找到,则创建该Servlet对象。
创建过程:Servlet引擎读取web.xml对象,获取到该Servlet的信息,封装init-param信息到ServletConfig对象中。利用反射技术创建Servlet对象,并调用init方法。
(8)Servlet引擎将客户端请求的数据进行封装。
Servlet引擎将客户端请求封装到request对象中,并创建一个响应头和响应体为空的响应对象。Servlet引擎将这两个对象作为参数传递到service(HttpServletRequest request,HttpServletResponse response)方法。
每一个客户端请求访问一次Servlet程序,Servlet引擎就创建一个对应的request对象和response对象。
(9)调用业务逻辑
调用逻辑方法service方法对请求进行处理,将response响应返回到服务器程序中。
(10)生成HTTP响应
服务器检查response对象中是否有数据,如果有,就生成HTTP响应。
(11)服务器将HTTP响应发送给客户端
(12)客户端浏览器显示服务器程序发送的HTTP响应信息。

二、Servlet的生命周期

生命周期即指:Servlet从创建到毁灭的整个过程。

(1)加载Servlet

Servlet的生命周期的第一个阶段是通过Servlet容器来实现加载(利用反射)以及初始化。

(2)初始化阶段

在Servlet实例化成功后,Servlet容器开始初始化Servlet对象并立即调用init()方法,用于初始化资源。

(3)处理请求

初始化后,Servlet实例已经准备好为客户端提供的服务。当Servlet实例位于服务请求时,Servlet容器将执行以下操作:
①它将创建ServletRequest和ServletResponse对象,如果发送的是HTTP请求,则Web容器会创建HttpServletRequest和HttpServletResponse对象
②在创建请求和响应对象之后,它会调用Servlet.service()方法。

(4)销毁Servlet

一般Servlet创建后,只有在服务器关闭时,Servlet容器才会销毁Servlet。

三、Servlet的使用

(1)Servlet的开发

Servlet的核心是Servlet,它是所有Servlet类必须直接或间接实现的一个接口。开发Servlet有三种方法,如下所示,也是发展的过程:
①实现Servlet接口:实现Servlet接口,重写方法,配置web.xml文件。
Servlet接口中有五个方法:

API文档截图
init():该init函数用于初始化该servlet,该函数只会被调用一次(当用户第一次访问该servlet时被调用)
destroy():销毁servlet实例(释放内存),关闭tomcat是调用
service():service函数用于处理业务逻辑,业务逻辑代码都写在这,当用户访问servlet时,都会调用该函数
getServletInfo():获取servlet信息,可选项
getServletConfig():获取servlet配置信息,可选项

②继承GenericServlet:继承GenericServlet,重写方法,配置web.xml文件

③继承HttpServlet:继承HttpServlet,重写方法,配置web.xml文件

(2)service方法、doGet方法和doPost方法的区别

①三个方法的介绍
Service是类GenericServlet中最重要的方法,每次客户向服务器发出请求时,服务器就会调用这个方法。开发人员如果想对客户的请求进行响应的话就必须覆盖这个方法,并在这个方法中加入自己的代码来实现对客户的响应。Service有两个参数(ServletRequest和ServletResponse),ServletRequest保存了客户向服务器发送的请求,而ServletResponse用来设置如何对客户进行响应。
doGet方法是用来处理get方式请求的。
doPost方法是用来处理post方式请求的。
②三个方法的执行顺序
不管是 get 方式或是 post 方式的请求,如果 自己写的Servlet 类中有 service() 方法,则优先调用 Service 方法。然后才会调用自己覆写的doPost()或是doGet()方法。
在没有 service 方法的情况下如果是 get 方式的请求所调用的处理请求的方法。
在没有 service 方法的情况下如果是 post 方式的请求所调用的处理请求的方法 。

(3)get请求和post请求的区别

①GET请求
请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是uniclde,即是说所有的非ASCII字符都要编码之后再传输。
②POST请求
POST请求会把请求的数据放置在HTTP请求包的包体中。因此,GET请求的数据会暴露在地址栏中,而POST请求则不会。
③传输数据的大小
在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。
显然,POST方式能够携带的数据量更大,例如传输文件就不能用GET,得用POST。
④安全性
POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。比如,在进行登录操作,通过GET请求,用户名和密码都会暴露再URL上,因为登录页面有可能被浏览器缓存以及其他人查看浏览器的历史记录的原因,此时的用户名和密码就很容易被他人拿到了。

(4)ServletRequest接口和ServletResponse接口

①ServletRequset接口
Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。
我们来看一下ServletRequest接口的重要的几个方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
②ServletResponse接口
javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法,但ServletResponse隐藏了向浏览器发送响应的复杂过程。
ServletRequest接口的最常用的方法就是getWriter方法:getWriter()可以获得可以向浏览器发送文本的java.io.PrintWriter对象。可以用它来发送html代码。不过在那之前要通过setContentType()设置响应类型为text/html。

(5)Request中文乱码问题的原因及解决

①中文乱码的原因
客户端和服务器端的编码与解码方式不一致。
②request中文乱码解决方法
A、post方式
post方式属于表单提交,参数存在于请求体中。
request.setCharacterEncoding("utf-8”)
B、get方式
get方式提交的参数会跟在请求行中的URL后边,服务器按照默认的iso-8859-1进行解码。
解决乱码——修改服务器端对URL参数的默认编码
在tomcat的server.xml中,设置元素的属性URIEncoding="UTF-8”即可。
③response中文乱码解决方法
在getWriter()方法被调用之前,通知浏览器服务器发送的数据格式:
response.setContentType("text/html;charset=utf-8”);

不贵于无过,而贵于改过,若有错误,欢迎提出!

猜你喜欢

转载自blog.csdn.net/weixin_44613100/article/details/105479298