1.servlet对象的生命周期
什么时候进行创建
默认情况下,Tomcat服务器启动的时候,Servlet对象并没有被实例化;
因为,servlet对象就是负责处理用户的请求,在请求还未发送之前,如果提前创建servlet对象,必然是耗费内存的;同时,如果这个servlet对象一直没有用户访问,那么这一个servlet对象就是垃圾。综上,servlet对象在并不是在服务器启动的时候创建,而是在用户发送请求时创建。
特殊情况下,如果我们想要在服务器启动的时候创建servlet对象,可以在XML文件中添加字标签,越小的整数代表优先级越高;
<servlet>
<servlet-name>StudentServlet</servlet-name>
<servlet-class>com.wangye.servlet.StudentServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StudentServlet</servlet-name>
<url-pattern>/servlet/student</url-pattern>
</servlet-mapping>
创建后的生命历程
在用户发送第一次请求时,创建执行servlet无参数构造方法,创建servlet对象【一次】
之后执行init() 方法,完成对象的初始化操作【一次】
-
应用:初始化连接池、初始化线程池……
当用户发送一次请求时,执行一次service()方法,请求几次,执行几次;【N次】
在服务器关闭的时候,销毁servlet对象的内存,执行destroy()方法;【一次】
-
应用:某些资源要关闭了,某些资源要保存了,不保存就没有了;
2.GET请求和POST请求
2.1 GET请求与POST请求的五点区别
2.1.1 地址栏回显与否
get请求发送数据的时候,数据会挂在URI的后面,并且在URI后面添加一个“?”,"?"后面是数据。这样会导致发送的数据回显在浏览器的地址栏上。(get请求在“请求行”上发送数据
http://localhost:8080/servlet05/getServlet?username=zhangsan&userpwd=1111post请求发送数据的时候,在请求体当中发送。不会回显到浏览器的地址栏上。也就是说post发送的数据,在浏览器地址栏上看不到。(post在“请求体”当中发送数据)
2.1.2传送的数据类型和数据量不同
get请求只能发送普通的字符串。并且发送的字符串长度有限制,不同的浏览器限制不同。这个没有明确的规范。get请求无法发送大数据量。
post请求可以发送任何类型的数据,包括普通字符串,流媒体等信息:视频、声音、图片。post请求可以发送大数据量,理论上没有长度限制。
2.1.3功能作用不同
get请求在W3C中是这样说的:get请求比较适合从服务器端获取数据。
post请求在W3C中是这样说的:post请求比较适合向服务器端传送数据。
2.1.4安全性不同
get请求是安全的。get请求是绝对安全的。为什么?因为get请求只是为了从服务器上获取数据。不会对服务器造成威胁。(get本身是安全的,你不要用错了。用错了之后又冤枉人家get不安全,你这样不好(太坏了),那是你自己的问题,不是get请求的问题。)
post请求是危险的。为什么?因为post请求是向服务器提交数据,如果这些数据通过后门的方式进入到服务器当中,服务器是很危险的。另外post是为了提交数据,所以一般情况下拦截请求的时候,大部分会选择拦截(监听)post请求。
2.1.5是否支持缓存
get请求支持缓存。
https://n.sinaimg.cn/finance/590/w240h350/20211101/b40c-b425eb67cabc342ff5b9dc018b4b00cc.jpg
任何一个get请求最终的“响应结果”都会被浏览器缓存起来。在浏览器缓存当中:
一个get请求的路径a 对应 一个资源。
一个get请求的路径b 对应 一个资源。
一个get请求的路径c 对应 一个资源。
......
实际上,你只要发送get请求,浏览器做的第一件事都是先从本地浏览器缓存中找,找不到的时候才会去服务器上获取。这种缓存机制目的是为了提高用户的体验。
如果我们的get请求不想要从缓存中获取数据,只要每一次get请求的请求路径不同即可,在末尾加上一个时间戳。
https://n.sinaimg.cn/finance/590/w240h350/20211101/7cabc342ff5b9dc018b4b00cc.jpg?t=789789787897898- post请求不支持缓存。(POST是用来修改服务器端的资源的。
post请求之后,服务器“响应的结果”不会被浏览器缓存起来。因为这个缓存没有意义。
2.2 GET请求和POST请求如何选择,什么时候使用GET请求,什么时候使用POST请求?
-
根据需求:你这个请求是想获取服务器端的数据,还是想向服务器发送数据。如果你是想从服务器上获取资源,建议使用GET请求,如果你这个请求是为了向服务器提交数据,建议使用POST请求。
-
大部分的form表单提交或提交敏感信息都是post方式,因为form表单中要填写大量的数据,这些数据是收集用户的信息,一般是需要传给服务器,服务器将这些数据保存/修改等。
-
其他情况都可以使用get请求。
-
不管你是get请求还是post请求,发送的请求数据格式是完全相同的,只不过位置不同,格式都是统一的,都遵循请求协议;
3.资源的跳转的两种方法:
-
第一种方式:转发
-
第二种方式:重定向
1.基本语法
-
转发的基本语法:
request.getRequestDispatcher("/b").forward(request,response);
注意:转发的时候,路径的写法要注意,转发的路径以“/”开始,不加项目名。因为转发机制是在服务器内部完成跳转的,它知道你的项目名,所以不需要添加项目名。转发的机制是一次请求,不管你转发了多少次。都是一次请求。
// AServlet转发到BServlet,再转发到CServlet,再转发到DServlet,不管转发了多少次,都在同一个request当中。
// 这是因为调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet。
2.重定向的基本语法:
response.sendRedirect("/项目名/dept/list");
注意:路径上要加一个项目名。因为我们的重定向是浏览器发送请求,请求路径上是需要添加项目名的。 以上这一行代码会将请求路径“/项目名/dept/list”发送给浏览器,浏览器会自发的向服务器发送一次全新的请求:/项目名/dept/list;
2.区别
-
形式上有什么区别?
-
转发(一次请求)
-
在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a ,最终请求结束之后,浏览器地址栏上的地址还是这个。没变。
-
-
重定向(两次请求)
-
在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a ,最终在浏览器地址栏上显示的地址是:http://localhost:8080/servlet10/b
-
-
-
转发和重定向的本质区别?
-
转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。
-
重定向:是浏览器完成的。具体跳转到哪个资源,是浏览器说了算。
-
3.如何选择?什么时候使用转发,什么时候使用重定向?
-
如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。
-
剩下所有的请求均使用重定向。(重定向使用较多。)
-
跳转的下一个资源有没有要求呢?必须是一个Servlet吗?
-
不一定,跳转的资源只要是服务器内部合法的资源即可。包括:Servlet、JSP、HTML.....
-
注意:转发会存在浏览器的刷新问题,有时候甚至会出现路径的拼接错误,要常按F12看发送的请求。
4.Session会话机制
可以参考这篇之前写的博客(Session详解(有案例验证))
5.域对象:
-
request(对应的类名:HttpServletRequest)
-
请求域(请求级别的)
-
-
session(对应的类名:HttpSession)
-
会话域(用户级别的)
-
-
application(对应的类名:ServletContext)
-
应用域(项目级别的,所有用户共享的。)
-
-
这三个域对象的大小关系
-
request < session < application
-
-
他们三个域对象都有以下三个公共的方法:
-
setAttribute(向域当中绑定数据)
-
getAttribute(从域当中获取数据)
-
removeAttribute(删除域当中的数据)
-
6.filter过滤器
-
Filter是过滤器。
-
Filter可以在Servlet这个目标程序执行之前添加代码。也可以在目标Servlet执行之后添加代码。之前之后都可以添加过滤规则。
-
一般情况下,都是在过滤器当中编写公共代码,例如判断用户是否登录的功能。
filter的生命周期
-
和Servlet对象生命周期一致。
-
唯一的区别:Filter默认情况下,在服务器启动阶段就实例化。Servlet不会。之所以会在启动阶段就进行初始化,是因为filter对象是对Servlet对象服务的,所以需要先于Servlet对象创建。
filter中的三个方法
-
init方法:在Filter对象第一次被创建之后调用,并且只调用一次。
-
doFilter方法:只要用户发送一次请求,则执行一次。发送N次请求,则执行N次。在这个方法中编写过滤规则。
-
destroy方法:在Filter对象被释放/销毁之前调用,并且只调用一次。
7.listener监听器
-
什么是监听器?
-
监听器是Servlet规范中的一员。就像Filter一样。Filter也是Servlet规范中的一员。
-
在Servlet中,所有的监听器接口都是以“Listener”结尾。
-
-
监听器有什么用?
-
监听器实际上是Servlet规范留给我们javaweb程序员的特殊时机。
-
特殊的时刻如果想执行这段代码,你需要想到使用对应的监听器。
-
-
Servlet规范中提供了哪些监听器?
我们可以将监听器理解成JS的事件,用户的行为或者服务器执行带相应的代码时,进行触发。所有监听器中的方法都是不需要javaweb程序员调用的,由服务器来负责调用,只有当某个特殊的事件发生(特殊的事件发生其实就是某个时机到了。)之后,被web服务器才会自动调用。
-
jakarta.servlet包下:
-
ServletContextListener
-
ServletContextAttributeListener
-
ServletRequestListener
-
ServletRequestAttributeListener
-
-
jakarta.servlet.http包下:
-
HttpSessionAttributeListener
-
- 该监听器需要使用@WebListener注解进行标注。
-
该监听器监听的是什么?是session域中数据的变化。只要数据变化,则执行相应的方法。主要监测点在session域对象上。
-
-
HttpSessionBindingListener
-
该监听器不需要使用@WebListener进行标注。
-
假设User类实现了该监听器,那么User对象在被放入session的时候触发bind事件,User对象从session中删除的时候,触发unbind事件。
-
假设Customer类没有实现该监听器,那么Customer对象放入session或者从session删除的时候,不会触发bind和unbind事件。
-
-
HttpSessionIdListener
-
session的id发生改变的时候,监听器中的唯一一个方法就会被调用。
-
-
HttpSessionActivationListener
-
监听session对象的钝化和活化的。
-
钝化:session对象从内存存储到硬盘文件。
-
活化:从硬盘文件把session恢复到内存。
-
- 该监听器需要使用@WebListener注解进行标注。
-
8.MVC架构
MVC 是 Model-View-Controller 的缩写。
为了便于项目的开发和部署,Web 应用程序分为基本的 3 个模块:模型、视图和控制器。
Model:负责处理数据处理和业务处理(数据库层)包括:service()功能层||Dao 处理数据库层 || pojo基本的java类
View:负责显示用户的内容(表示层)例如:jsp、html文件
Control:负责按照用户操作(中间调度层)进行操作
层与层之间通过接口进行调度,一个完整的项目分层应该是如下所示: