-
Servlet生命周期
- init()::::::服务类第一次请求的时候,创建对象就会调用init()方法初始化类对象信息
- 第一次访问被创建出来-------------默认是一个负数值
- 在服务器启动的时候,被创建出来--------------这个时候是设置为 0或者正整数的
- 注意:
- 标签[load-on-startup]是用来标记容器是否在启动的时候就加载这个Servlet类,实例化这个类并执行init()方法
- 标签[load-on-startup]必须是一个整数表示Servlet加载的顺序
- 当值大于等于0的时候表示容器在启动的时候就加在初始化这个Servlet类
- 当值小于0的时候表示容器在该Servlet被选中的时候才会去加载----->不选择是不会主动加载的
- 当正数值越小表示在容器中的优先级越高,应用启动的时候就月线加载
- 当值想通的时候容器会自动选择一个Servlet去加载
- 在Servlet中这个init()方法只会加载一次,说明一个Servlet在内存中只会存储一个对象,也表明这个Servlet是单例的哟想要床架新的对象必须先销毁之前的对象,对象销毁之后再被穿件出来也不是相同的对象
- 狭义单例:一个类在内存中有且仅有一个类对象,而且自始至终都只有同一个对象---->做法:把该累的构造器私有化
- 广义单例:只要满足在整个系统中有且仅有一个示例即可,不一定是同一个对象----->Servlet中的对象就是广义的
- 在Servlet 3.1规范中,当自定义Servlet类没有实现,SingleTheadModel接口的时候,Servlet类才是单位,如果实现该接口,每次请求Servlet类的时候,容器都会先创建一个新的Servlet类对象
- 面试题:Servlet容器,如何保证在多线程环境下访问数据安全性问题
- Servlet容器默认采用打你多线程方式处理多个请求
- 当web容器启动的时候(或者客户端发送请求的时候),Servlet对象就会被加载并实例化,
- 容器初始化主要就是读取配置文件----web.xml---在Tomcat容器中也有一个web.xml和server.xml--在server.xml中可以设置线程池中的数目,初始化线程池需要通过web.xml
- 当客户端请求到达的时候Servlet容器可以通过线程调度它管理下的线程池中的等待执行的线程
- 线程执行Servlet类中的service方法
- 当线程执行完毕就会归还线程到线程池中
- 当多个用户同时访问同一个Servlet类的时候就会存在现成数据安全问题,
- 解决方法:不要Servlet类当中定义成员变量,避免多个线程同时操作同一份资源,如果定义了就只能查询不要修改
- Servlet容器默认采用打你多线程方式处理多个请求
- 注意:
- service():::::每次发送请求的时候会被执行。
- ServletRequest:代表请求,会把Http请求的所有信息装配到ServletRequest对象中
- ServletResponse:代表响应,会把Http响应中的信息装配到ServletReponse对象中
- 手动指定话Servlet类对象创建时机---->通过在Servlet中配置标签[load-on-startup]标签
- destory():Servlet类对象被销毁的时候就会被调用--->比如代码该了,类对象就被销毁了,服务器被关闭
- init()::::::服务类第一次请求的时候,创建对象就会调用init()方法初始化类对象信息
Servlet 3.0
在以前的时候,每次有一个新的Servlet类都要都要去修改web.xml,当服务器运行的时候会加载web,xml如果Servlet类对象很多那么就会加载很慢,.3.0提供了注解
实现Servlet接口就是一个Servlet类
-
步骤
-
创建一个Servlet类,选择Servlet3.0以上
-
在Servlet类上面添加@WebServlet()
-
在@WebServlet请求资源路径--不要忘记前面的斜杠)的小括号里面写url路径---->/demo01表示只能通过demo01来访问ServletDemo01,如果想要多个访问url用逗号隔开
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface WebServlet { String name() default ""; //相当于web.xml中的servlet-name标签 String[] value() default {}; // String[] urlPatterns() default {}; int loadOnStartup() default -1;
-
欢迎页面
404
当我们向浏览器中输入我们的服务器地址,路径url格式:http://localhost:8080/day48/,此时tomcat会自动按照在web.xml文件汇总配置的welcome-file-list标签列表从上到下依次查找对应的web资源,如果全部找完都没有发现对应的资源,服务器就会给浏览器客户端返回一个404状态码(表示没找到web资源)--->有可能就是web路径写错了,找到了就是一个欢迎界面.访问当前应用根目录下的web文件夹下的资源
注意:我们访问的一般都是web文件夹下的资源,但是有一个文件夹下面的资源直接糖果浏览器是访问不道德,这个目录就称为安全目录(WEB-INF)--->只能他通过服务器内部来访问
两种访问web资源的方式
-
内部转发:---->服务器行为
-
重定向:------>客户端行为
Servlet相关配置
我们主要配置url-pattern标签客户端访问web应用资源的路径
String[] urlPattern():一个Servlet可以配置多个访问路径 @WebServlet({"/demo01","/demo02","/demo03"....})
路径定义的规则:
/xxx:路径匹配/完全匹配
/xxx/yyy/...:多层路径匹配或者目录匹配.do 或者 .action:---->叫做扩展名,服务器后面带有一个后缀,,,@WebServlet(".do") //表示再服务器访问的时候写啥都是可以的
注意: *.do 或者 *.action是不需要斜杠的
/ 缺省配置:url-padding只写一个斜杠其他啥也不写,当访问web应用中的资源(Servlet)都不匹配,找不到的话就会寻找缺省配置的Servle
让这个缺省配置的Servlet来处理请求资源,当前这个Servlet能处理的资源包括Servlet和静态资源,但是jsp资源解决不了
/ * 表示全部处理,包含静态,动态和jsp都能包含到,直接借助Servlet中访问方式:内部转发和重定向
HTTP
超文本传输协议,是互联网中应用最广泛的一种网络协议
传输协议:定义了客户端和服务器端通信时,发送数据的[ 格式 ]
-
特点
- 基于TCP/IP的协议
- 默认端口号是: 80
- 基于请求与响应模型的,一次请求对应一次响应
- 无状态的:每次请求之间是相互独立的,每次请求之间不能进行数据的交互
-
历史版本
-
1.0:每次请求都要建立连接,每次都是新连接
-
1.1---->主流常用的版本,持久连接(不用每次都建立新连接,这也是最大的变化),连接可以多次复用
不用再声明:Connection:keep-alive
-
如果发现客户端和服务器端一段时间没有活动,就会主动关闭连接,如果在客户端发送最后一个请求时,这个歌请求如果发送了Connection:close就是明确要求服务器关闭TCP连接
-
目前大多数浏览器对于同一个域名最多同时允许建立六个持久连接,提高了带宽的利用率,
-
加入了管道机制,在同一个连接里面允许发送多个请求,增加了并发性,改善了HTTP协议的效率
-
-
2.0
- 为了解决利用率不高的问题继续优化,提出了2.0版本的操作,增加了一个双工模式.不仅客户端能够同时发送多个请求,服务器端也能同时处理多个请求.解决了队列头堵塞问题.
-
-
协议的组成与过程
HTTP协议它是由HTTP请求和HTTP响应组成的,当在客户端中输入一个url地址,浏览器会把我们的请求信息封装为一个HTTP请求的格式发送个服务器,服务器端收到这个请求消息之后,服务器端就会解析这个请求消息,,,,解析这个请求消息将他装配到ServletRequest中,做完业务逻辑之后,会组织响应数据服装为一个HTTP响应的格式,返回给浏览器客户端-----------这个过程就是请求与响应----由此可以看出没有请求就没有响应.
-
抓包分析
使用谷歌知道的抓包工具,可以看到数据之间相互传播的课程
HTTP请求
get请求-----HTTP默认的请求方式是get请求(直接在客户端的地址栏中输入url和使用),对于form表单可以开于指定请求方式为post(是可以的不会有影响)
// 请求行:请求方式 请求路径 http版本号
GET /checkUser?username=admin&password=123456 HTTP/1.1
// 本机服务器的ip地址 域名
Host: localhost:8080
// 连接的方式 长连接
Connection: keep-alive
// 告诉服务器,自己支持你这中操作,我能读懂服务器发送的的信息,建议使用https而不是用http
Upgrade-Insecure-Requests: 1
//用户使用的浏览器客户端的内核 还包括操作系统相关的信息
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
// 接收的数据格式
// 告诉服务器端浏览器客户端能够接收的哪种类型的数据
Accept:
// mime类型 大范围/小范围
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
// 来源地--->浏览器通知服务器,当前的请求时来自于哪个地方
// Referer:经常用于防盗链 防止盗取我的连接信息 如果你是直接请求资源,没有referer
Referer: http://localhost:8080/
// 接收的压缩格式 浏览器通知服务器我可以接收哪些类型压缩格式的数据
Accept-Encoding: gzip, deflate, br
// 浏览器可支持的语言
Accept-Language: zh-CN,zh;q=0.9
// Cookie JSESSIONID
Cookie: Idea-ac70df0d=96318eda-906d-4909-81b5-89db73f5358a; JSESSIONID=43EE4E93151302CD4B10579871CB8328
POST请求:
POST /checkUser HTTP/1.1
Host: localhost:8080
Connection: keep-alive
// 内容的长度
Content-Length: 30
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
// 如果是post请求在请求体中的数据使用url编码
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: Idea-ac70df0d=96318eda-906d-4909-81b5-89db73f5358a; JSESSIONID=43EE4E93151302CD4B10579871CB8328
// 请求体内容
username=admin&password=123456
HTTP响应
// 响应行 http协议 状态码
HTTP/1.1 200
// 响应头
// 响应正文的内容长度 当前为0
Content-Length: 0
// 响应的时间
Date: Tue, 12 Jan 2021 07:49:14 GMT
Keep-Alive: timeout=20
Connection: keep-alive
常用的状态码
常用状态码 | 描述 |
---|---|
200 | 请求成功 |
302 | 重定向 |
304 | 读取本地缓存的文件 |
404 | 请求的页面或资源找不到 |
405 | 请求方式不正确(比如:浏览器客户端使用get请求,服务器端接收使用的post就会报405) |
500 | 服务器端代码错误,需要修改源代码 |
Servlet体系结构
在实际开发中我们创建Servlet类,大多数时间都是使用的service方法,由于必须遵从Servlet接口而不得不去重写其他的抽象方法,就很烦
这些方法大多数时候是闲置不用的,在Servlet中有一个HttpServlet类就把Servlet中我哥抽象方法封装起来了.我们以后可以定义一个类来继承这个类,最后的类也是一个Servlet类
GenericServlet基本上继承了Servlet接口中所有的抽象方法,处理service方法,需要子类来实现,但是由于客户端发送请求方式的区别,在service方法中还要做具体判断,不方便,他的子类HttpServlet当中实现了servlet方法,做了区分不同请求方式的实现,对外提供了七个请求的方法,由于目前阶段我们只使用get和post请求方式,所以关注重点也在doGet和doPost方法
查看源码发现doGet和doPost方法两个参数分别是HttoServletRequest和HttpServletResponse,就是我们需要的请求对象和响应对象