Servlet 基本概念
Servlet 基本概念
一、基本概念
Web客户(浏览器):允许用户请求服务器上的某个资源,并向用户显示请求结果
Web服务器:接收客户请求,然后向客户返回一些结果
HTML:告诉浏览器怎样把内容呈现给用户
HTTP:Web客户与服务器通信所用的协议
二、HTTP 请求
1. GET 与 POST 的区别
GET:从服务器拿些东西回来
- 总字符数是有限的
- 发送的数据会追加到 URL 的后面,在浏览器地址栏中显示出来,所以你发送的数据会完全暴露
- 使用
?将路径和参数分隔,各个参数之间用&分隔 - 资源的路径以及增加到URL的所有参数都会包含在请求行中
,不安全 - 幂等
请求行:
GET /select/selectColor.jsp?color=black HTTP/1.1
请求首部:
...
POST:可以请求某些东西,与此同时向服务器发送一些表单数据
这些数据称为 消息体 或 负载
- POST有一个体
- 非幂等
请求行:
POST /advisor/selectColer.do HTTP/1.1
请求首部:
...
Accept: text/html,text/xml
...
消息体/负载:
color=black
2. 幂等与非幂等
幂等:同一个请求可以做两次,而不会对服务器产生负面作用
幂等方法:GET,PUT,DELETE,HEAD,OPTIONS
非幂等方法:POST(重复提交同一个 POST 请求,可能会创建多个资源。例如,重复提交订单会生成多个订单)
三、HTTP 响应
HTTP响应首部:告诉浏览器使用了什么协议,请求是否成功,以及体中包括何种类型的内容
体:包含了让浏览器显示的具体内容
响应首部:
web服务器使用的协议版本 响应的HTTP状态码 状态码的相应文本
HTTP/1.1 200 OK
...
Content-Type: text/html
...
体:
<html>
...
</html>
-
content-type(内容类型)响应首部的值称为 MIME 类型
-
MIME 类型告诉浏览器要接收的数据是什么类型,这样浏览器才能知道如何显示这些数据
-
MIME 类型值与 HTTP 请求首部中 Accept 所列的值有关
四、执行流程
1. Web服务器主机中的三个应用
- Web 服务器应用(Nginx、Apache):只提供静态页面
- 辅助应用(Servlet):生成非静态的及时页面,Web 服务器会把参数移交给 Servlet,由Servlet 为客户生成一个响应
- Web容器应用(Tomcat、Jetty):服务器不是把请求交给 servlet 本身,而是交给部署该 servlet 的容器,要这个容器向 servlet 提供 HTTP 请求和响应,而且要由容器调用 servlet 的方法
web浏览器->web服务器主机[web服务器应用->web容器应用->servlet]
2. Web 容器应用
Web容器应用:管理和运行 servlet
- 通信支持:无需自己实现连接
- 生命周期管理:控制servlet的生命周期,不用太多地考虑资源管理
- 多线程支持:容器会自动地为它接收的每个servlet请求创建一个新的Java线程
3. 请求的执行流程:
- 用户点击一个连接,其 URL 指向一个 servlet 而不是一个静态页面
- 容器发现这个请求要的是一个 servlet,会创建两个对象:
- HttpServletRequest
- 可以得到首部、cookie、会话等
- HttpServletResponse
- 可以设置contentType、得到输出流、设置首部、cookie、状态等
- HttpServletRequest
- 容器根据请求中的 URL 找到正确的 servlet,为这个请求创建或分配一个线程(每个客户的每个请求都在单独的线程中运行,任何时刻有多少客户请求就至少有多少并发的线程,线程的数量受容器的约束,当客户请求数量超过上限时,有些客户就必须等待),并把请求对象和响应对象(每个客户的每个请求都有自己的)传递给这个 servlet 线程
- 容器调用 servlet 的 service() 方法。service() 方法会根据请求的不同类型调用 doGet() 或 doPost() 方法
- doGet() 方法生成动态页面,并把这个页面填入响应对象
- 线程结束,容器把响应对象转换为一个 HTTP 响应,把它返回给客户,然后删除请求对象和响应对象
五、会话管理
1. HttpSession
[相同的客户、相同的 servlet、不同的请求、不同的线程]->相同的会话
HTTP 协议使用的是无状态连接,对于容器而言,每个请求都来自于一个新用户
对客户的第一个请求,容器会生成一个唯一的会话 ID,并通过响应把它返回给客户。
客户再以后的每一个请求中发回这个会话 ID。容器看到 ID 后,就会找到匹配的会话,并把这个会话与请求关联
2. Cookie
ID -> cookie
HTTP响应
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=0AAB6C8DE415
...
HTTP请求
POST /select/selectColor.do HTTP/1.1
Cookie: JSESSIONID=0AAB6C8DE415
...
容器几乎会做 cookie 的所有工作
- 在响应中发送一个会话 cookie:
HttpSession session = request.getSession();- 即在服务方法中请求一个会话,余下的所有事情都会自动完成
- 你不用自己建立新的HttpSession对象
- 你不必生成唯一的会话ID
- 你不用自己建立新的Cookie对象
- 你不用把会话ID与cookie关联
- 你不用在响应中设置Cookie
- 从请求得到会话ID:
HttpSession session = request.getSession()
IF(请求包含一个会话ID cookie)
找到与该ID匹配的会话
ELSE IF(没有会话ID cookie OR 没有与此会话 ID 匹配的当前会话)
创建一个新的会话
如果只想要一个已经有的会话呢?
- 可以调用getSession(false),调用这个方法要么得到null,要么得到一个已经有的HttpSession
如果客户禁用cookie怎么办?
- 禁用cookie的客户会忽略 Set-Cookie 响应首部
- 可以进行URL重写:
URL + ;jsessionid=1234567
cookie实际上就是在客户端和服务器之间的一小段数据(一个名/值String对)
- 可以通过Servlet API 定制Cookie
- HttpServletRequest
- HttpServletResponse
- Cookie
// 创建和设置cookie
Cookie cookie = new Cookie("username", name)
cookie.setMaxAge(30*60); // 在客户端上存活30分钟
response.addCookie(cookie);
五、会话迁移
在一个集群环境中,容器可能会完成负载平衡,取得客户的请求,把请求发送到多个JVM上,这就意味者每次客户请求时,最后有可能到达一个servlet的不同实例
每个VM中有一个ServletContext,每个VM上的每个servlet有一个ServletConfig。但是对于每个Web应用的一个给定的会话ID,只有一个HttpSession对象,而不论应用分布在多少个VM上
在任何时刻,会话只存在于一个位置,对于一个给定的Web应用,相同的会话ID不会出现在两个VM中
[VM1 钝化] -- 迁移 --> [VM2 激活]
更多推荐




所有评论(0)