生命周期
首先聊聊tomcat容器。
什么是容器,我自己想了一个最简单的答案:就是一个集合,以及对该集合的操作整合在一起成为一个容器。
那么tomcat容器是干什么:简单的说就是servlet集合,以及对它的调用。当然,它底层应该有许多的流的操作,用于网络上的输入输出,并且还封装了许多网络通信相关的内容。
题外话:tomcat有个默认的servlet name:default
接下来聊聊servlet是如何创建,如何go die的。
首先,servlet是由容器创建的(我们写web时,不需要自己去new一个servlet),创建时机可以由自己手动设置其为容器启动时自动创建,默认是请求时创建。
::web.xml中进行设置,或者交给spring框架进行管理(即springMVC的DispatherServlet,spring框架只需这一个servlet,结合springMVC容器可以处理一个项目中的所有请求)
其次,当容器关闭时,则会自动销毁servlet
servlet的体现生命周期的四个方法 :
构造
:init
:service
:destroy
最常用的四个属性
- request
1、用户怎么访问你的服务器的?答案:通过请求(在应用层层面上)。
2、一个请求长什么样子,以至于可以让服务器认识它。首先得有请求行,请求行里有着着URL(统一资源定位)。通过URL可以是你的资源具有唯一性,可以在庞大且复杂的网络里定位你的资源。当然,请求行里不止URL,还有请求类型的方法字段(GET/POST),请求所使用的协议(如HTTP 1.1),接下来就是请求头里的内容,比如Cookie等等(作者菜蔬学前,记得不多)。
除了请求头,还有消息体。说到消息体,就需要注意一点,GET请求的请求体里的内容一般会被代理和缓存过滤。使用GET传递参数,只是把参数拼接在了URL后面(?&=)。而POST请求就是把参数数据放在了消息体里了。也因为GET请求这种传参方式,并由于URL长度限制(URL 的最大长度是 2048 个字符),实际开发中,我们对不重要的、少量的数据我们才考虑使用GET请求,而对于重要的、大量的数据,应该考虑POST请求方式。
注意:GET请求或者说URL只能携带ASCII字符参数,而POST请求携带的数据可以为二进制。这表示我们只能使用POST请求上传文件或其他非ASCII字符的参数数据。而不论是超链接、地址栏直接输入、表单、ajax默认都是使用GET请求。其中表单和ajax可以选择使用POST请求。
3、request就是一个封装请求的请求对象,该对象是tomcat自动封装好的。我们可以在上面存值,然后通过转发(调用request对象的getRequestDispather
方法即可)(不能是重定向)jsp页面将request上存的值取出(通过key-value的形式)。
那么为什么不能是重定向页面:因为转发是将要转发的页面地址和页面直接全部发送至客户端(即一次请求一次响应),而重定向是先发送页面地址,然后浏览器得到该地址,在请求该地址指向的资源,然后tomcat服务器再发送该资源。(即两次请求两次响应),那么当第二次请求时,原来的请求对象就失效了,无论你在上面存什么值,都是无用功。通过地址栏的变化我们也可以看出:转发时地址栏显示的第一次请求的地址,而不是页面地址。但重定向时,地址栏上显示的是页面地址。
为什么是jsp页面 :因为我们再jsp页面里可以利用小脚本取出request中的数据(栗子:request.getParameter();
)。
为什么jsp的小脚本可以直接使用Request对象,都不用new出来:
jsp知识补充:jsp动态页面,其实本身就是servlet,只不过可以与html相结合。其运行原理为:当有请求访问jsp页面时,就会生成一个xxx_jsp.java(该类继承了HttpServlet,所以说jsp本身就是servlet),随后编译为class文件,其内部就是将html内容结合小脚本里自动生成的数据以流的形式发送给客户端浏览器(out.print(xxx);
)。
其有九大内置对象(request
,response
,session
,application
,page
,pageContext
,out
,exception
,config
),这九个对象对应着servlet。小脚本说完了,接下来就是EL表达式了,它主要就是用来输出数据的(栗子:${requestScope.people!=null}
)。在这里我们需要建立域的概念,比如:pageScope
、requestScope
、sessionScope
、applicationScope
,域范围一个比一个大,我们若不直接像栗子一样通过打点的方式获取指定域的值,则默认是从小域开始找,即从pageScope开始找,若没找到相关的key,就升到requestScope域去找。也可以通过:param
获取url上的参数。
案例:
GET请求
POST请求:
- response
1、有请求就有响应,我们可以通过这个响应对象设置一些响应信息。比如,状态响应码等。
2.如果不想直接发送页面可通过getWriter
方法获取输出流,通过它我们可以只传输字符串或脚本。
3.前端的下载功能,也是依靠response对象的,即设置响应头信息(告诉浏览器,我们将数据以附件的形式进行发送),浏览器接收附件。
4.重定向实现也是依靠response,调用其sendirect
方法传入页面地址即可。
以上的重定向和转发需注意,当我们在service或者doGet、doPost这三个处理请求的方法里,调用了重定向或转发的那两个方法之一,这并不代表return。
程序依然会向下执行。
可能出现的错误:在一条跳转页面的语句下又来了一条跳转页面的语句(若如此做,直接抛出异常,因为服务器无法依靠这样的方式,让客户端连续自动跳转页面)。
:
- session
1、存储在服务端。
2、当用户打开浏览器后,第一次点击你的网站的时候,即第一次访问你的服务器时,会有一个请求发送至你的服务端。当你通过request对象调用getSession
方法时,它会在存放session的地方获取对应的session【通过sessionId
】,若是该请求不包含sessionId,则默认创建一个session,你可以手动设置其是否自动创建。jsp默认是创建session。
3、session内存储的值在一个会话期间都有效。何为一个会话期间:从你打开浏览器到关闭浏览器期间。因此我们可以将登录验证信息存放至session里,以免重复登录。
4、session的核心就是sessionId,而sessionId不仅存在于服务器,还存在于客户端的cookie里,通过请求中的cookie中的sessionId来标识或者说区别各个客户端。因此,当客户端的浏览器禁用了cookie,session也就失效了。
5.session默认存放在服务器的一个文件中(当tomcat手动关闭,会将内存中的session持久化处理),session也可以放在内存或数据库。
6.当一个session会话超过某个时间(默认是30分钟),自动失效。可以手动设置该时间(即最大不活跃时间)(栗子:session.setMaxInactiveInterval();)
,或者调用invalidate
方法手动销毁。
:
- cookie
1、存储在客户端。
2、cookie里存放了sessionId,我们通过cookie就可以在发送请求后,服务端将该请求中的cookie取出,再从cookie中取出sessionId,通过该id找到对应的session,之后就可以提供相应的服务啦。
3.我们要给客户端发送一个cookie用以之后的验证等操作,我们可以先new一个cookie,然后调用response对象的addCookie方法,等你进行重定向或转发的时候,tomcat就会顺带帮你把这个cookie发送过去啦。
为什么说浏览器关闭,session就立即失效:该问题可以扩展至session、sessionId、cookie之间的原理,可参考
https://blog.csdn.net/weixin_43625577/article/details/92393581
: