互联网通信流程(含servlet)

1. 前言

如今的Java开发人员实际上可以称为“Spring开发人员”,所有的开发流程的内部细节都由Spring框架封装好的,所以我们在实际开发中就很少考虑其中的细节。然而若想成为一名高级开发工程师,而不是码农,必须对其底层的实现逻辑了如指掌。

依鄙人所见,servlet就是Java做web开发的精髓所在,完全掌握servlet非常重要。

虽然servlet使用的技术的技术比较老旧,但是它的思想是值得牢记在心的。

2. 互联网通信流程

两台计算机通过网络实现文件共享行为,就是互联网通信。
通信角色氛围客户端和服务端,有的节点可能既是客户端又是服务端。

2.1 通信模型

2.1.1 C/S通信模型

客户端向指定服务端发送请求,索要资源文件,并将服务端返回的二进制数据解析展示。
服务端用于接收来自于特定的客户端发送的请求,在接收到请求之后在服务端上定位被访问的资源文件,将文件内容以二进制形式通过网络发回客户端。
C/S普遍用于个人娱乐市场,比如微信、淘宝、优酷、英雄联盟等,在企业办公应用较少。
优点是安全性较高,也能降低服务端工作压力;缺点是增加客户获得服务成本(需要下载),且更新较为繁琐。

2.1.2 B/S通信模型

浏览器可以向任意服务器发送请求,索要资源文件,并将服务端返回的二进制数据解析展示。
服务端可以处理任意浏览器发送的请求,在接收到请求之后在服务端上定位被访问的资源文件,将文件内容以二进制形式通过网络发回浏览器。
B/S既适用于个人娱乐市场,也适用于企业日常活动。
优点是不会增加用户获得服务成本(不用下载对应软件),也不用频繁更新浏览器,缺点是服务端计算机工作压力巨大。

2.2 共享资源文件

可以经过网络进行传输的文件

2.2.1 静态资源文件

文档、图片、视频等
可以在浏览器编译执行的命令(html、css、js)

2.2.2 动态资源文件

不能在浏览器执行的命令(.class等)
动态文件被索要时,需要服务器处理逻辑,将运行结果返回给浏览器。

无论是静态还是动态,都是以二进制形式返回浏览器的。



3. servlet

3.1 servlet是什么

javaee的一种规范,http服务器操作动态资源文件的规范

servlet的命令、代码都是老旧代码了,不必记住它们,只要记住思想就好了。

3.2 servlet的生命周期

  • 所有的servlet的实例对象,都是由http服务器负责创建,开发人员不得手动创建。
  • 默认情况下http服务器接到对当前servlet实现类第一次请求时创建实例对象。
  • 在Http服务器运行期间,一个Servlet实现类只能被创建出一个实例对象
  • 在Http服务器关闭时刻,自动将网站中所有的Servlet对象进行销毁

3.3 servlet对象

3.3.1 response对象

响应对象,主要任务是:

  1. 将执行结果以二进制形式写入到响应体
  2. 设置响应头中content-type属性值,从而控制浏览器使用对应编译器将响应体二进制数据编译为文字、图片、视频、前端代码命令
  3. 设置响应头中location属性,将一个请求地址赋值给location从而控制浏览器向指定服务器发送请求(重定向)

3.3.2 request对象

请求对象,主要任务是:

  1. 读取http请求协议包中请求行的信息
  2. 读取http请求协议包中请求头(get)或请求体(post)中请求参数信息
  3. 代替浏览器向http服务器申请资源文件调用

3.3.3 request和response的生命周期

  • 在Http服务器接收到浏览器发送的Http请求协议包之后,自动为当前的Http请求协议包生成一个【请求对象】和一个【响应对象】
  • 在Http服务器调用doGet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行
  • 在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】销毁
  • 【请求对象】和【响应对象】生命周期贯穿一次请求的处理过程中
  • 【请求对象】和【响应对象】相当于用户在服务端的代言人

3.4 不同servlet交互

3.4.1 重定向

工作原理:用户第一次手动发送请求,浏览器处理完请求后,还需要另一个servlet完成接下来的操作,就在响应协议包的状态行写302,将第二个servlet的地址写到响应头的location属性,由浏览器自动发送第二次请求,完成剩余任务。

请求次数>=2,但是只有第一次用户手动发送,其余都是浏览器自动发送
因为浏览器发送请求默认为get方式,所以重定向请求方式一定是get

缺点:需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间。

3.4.2 请求转发

工作原理:用户第一次手动发送请求,浏览器处理完请求后,还需要另一个servlet完成接下来的操作,就通过当前的请求对象代替浏览器向服务器发送请求,调用其完成剩余任务。

无论涉及多少个servlet,浏览器只用发起一次请求,节省浏览器与服务器之间往返速度,提高服务处理速度。
所有servlet接收的请求方式都与浏览器发送的请求方式保持一致。

3.4.3 servlet数据共享

四种数据共享方案

  1. ServletContext接口
    ServletContext对象称为“全局作用域对象”,每个网站都有一个,相当于一个Map,每个servlet都可以存或取其中对象。
    全局作用域对象生命周期贯穿网站整个运行期间。

  2. Cookie类
    cookie是两个来自同一网站的servlet为同一用户服务时,存放当前用户私人数据的载体,只能存储字符串数据,一个cookie对象只能存储一条数据。
    服务器把cookie对象创建出来,放到响应头返回给浏览器,浏览器将cookie存到缓存中,发起下次请求时,将之前保存的cookie写到请求头发送到服务器,这样另一个servlet可以从cookie中拿到数据。
    默认情况,浏览器关闭,cookie对象就被销毁掉;我们可以手动设置cookie存储在硬盘上,并设置自动销毁时间。

  3. HttpSession接口
    HttpSession对象被称为“会话作用域对象”,存储在服务器中,可以存储任意数据类型的数据,使用map集合,可以存储任意数量的数据。
    Tomcat为每一个HttpSession对象设置空闲时间,默认30分钟,如果当前HttpSession对象空闲时间达到30分钟,此时Tomcat认为用户已经放弃了自己的HttpSession,就会销毁掉这个HttpSession。

  4. HttpServletRequest接口
    这个对象叫做“请求作用域对象”,只能在请求转发的时候使用,因为请求转发多个servlet共用同一个request和response。

3.5 监听器

此概念了解即可。

监听器接口用于监控【作用域对象生命周期变化时刻】以及【作用域对象共享数据变化时刻】

  1. ServletContext
    全局作用域对象
  2. HttpSession
    会话作用域对象
  3. HttpServletRequest
    请求作用域对象

3.6 过滤器和拦截器

3.6.1 分别是什么

过滤器(filter)
拦截器(intercepter)
过滤器是在servlet学的,拦截器是在springmvc学的

3.6.2 实现逻辑

过滤器:实现Filter接口,重写init()、doFilter()、destroy()三个方法
拦截器:实现HandlerInterceptor接口,重写preHandle()、postHandle()、afterCompletion()三个方法。

相比过滤器,拦截器的实现方法更不好理解
拦截器是链式调用,一个应用可以存在多个拦截器,一个请求可以触发多个拦截器,每个拦截器的调用根据声明顺序依次执行。

preHandle():在请求处理前调用,如果返回false,请求直接结束,拦截器失效。
postHandle():拦截器的处理逻辑。在多个拦截器同时作用时,postHandle()的调用顺序和preHandle()相反(先进的后出)
afterCompletion():在整个请求结束后执行的逻辑。

过滤器和拦截器都体现了AOP的编程思想。

3.6.3 过滤器和拦截器的不同

1)底层实现逻辑

过滤器基于函数回调
拦截器基于反射(动态代理)实现(下面的方法参数省略)

我们自定义的过滤器,实现了doFilter()方法,实际上我们处理逻辑是filterChain.doFilter(),ApplicationFilterChain是这个filterChain参数的实现类,这个类里有一个doFilter(),这就是回调方法。

每个xxxFilter执行doFliter()过滤逻辑后,执行filterChain.doFilter(),实现函数回调。

2)使用范围

过滤器实现的javax.servlet.Filter接口,是在servlet规范中定义的,也就是说过滤器依赖Tomcat等容器,所以只能在web程序中使用。

拦截器是一个spring组件,由spring容器管理,可以单独使用,不必依赖web服务器。

3)触发时机

互联网通信流程(含servlet)_第1张图片

过滤器几乎可以对所有进入容器中的请求起作用,而拦截器只会对controller中请求或者静态资源的访问起作用

拦截器加载的时间点在spring将对象注入容器之前,所以在拦截器类中使用@Autowired注册会失效

4)生命周期

一个过滤器实例只能在容器初始化时调用一次
拦截器充分体现了AOP思想,例如在调用某方法前实现逻辑,在调用后实现逻辑等。

一个拦截器实例在一个controller生命周期内可以多次调用。

你可能感兴趣的:(servlet,java,开发语言)