Web基础和HTTP协议
- ┌─────────┐
- ┌─────────┐ │?????????│
- │O ???????│ ├─────────┤
- ├─────────┤ │?????????│
- │ │ ├─────────┤
- │ │ │?????????│
- └─────────┘ └─────────┘
- │ request 1 │
- │─────────────────────>│
- │ request 2 │
- │─────────────────────>│
- │ response 1 │
- │<─────────────────────│
- │ request 3 │
- │─────────────────────>│
- │ response 3 │
- │<─────────────────────│
- │ response 2 │
- │<─────────────────────│
- ▼ ▼
我们注意到HTTP协议是一个请求-响应协议,它总是发送一个请求,然后接收一个响应。能不能一次性发送多个请求,然后再接收多个响应呢?HTTP 2.0
可以支持浏览器同时发出多个请求,但每个请求需要唯一标识,服务器可以不按请求的顺序返回多个响应,由浏览器自己把收到的响应和请求对应起来。可见,HTTP 2.0
进一步提高了传输效率,因为浏览器发出一个请求后,不必等待响应,就可以继续发下一个请求。
HTTP 3.0
为了进一步提高速度,将抛弃TCP
协议,改为使用无需创建连接的UDP
协议,目前HTTP 3.0
仍然处于实验推广阶段。
什么是Servlet
在JavaEE
平台上,处理TCP
连接,解析HTTP
协议这些底层工作统统扔给现成的Web
服务器去做,我们只需要把自己的应用程序跑在Web
服务器上。为了实现这一目的,JavaEE
提供了Servlet
API
,我们使用Servlet API
编写自己的Servlet
来处理HTTP
请求,Web
服务器实现Servlet
API
接口,
实现底层功能.
- // WebServlet注解表示这是一个Servlet,并映射到地址 hello.do
- @WebServlet(urlPatterns = "/hello.do")
- public class HelloServlet extends HttpServlet {
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- // 设置响应类型:
-
- resp.setContentType("text/html");
- // 获取输出流:
-
- PrintWriter pw = resp.getWriter();
- // 写入响应:
-
- pw.write("<h1>Hello, world!</h1>");
- // 最后不要忘记flush强制输出:
-
- pw.flush();
- }
- }
一个Servlet
总是继承自HttpServlet
,然后覆写doGet()
或doPost()
方法。注意到doGet()
方法传入了HttpServletRequest
和HttpServletResponse
两个对象,分别代表HTTP
请求和响应。我们使用Servlet API
时,并不直接与底层TCP
交互,也不需要解析HTTP
协议,因为HttpServletRequest
和HttpServletResponse
就已经封装好了请求和响应。以发送响应为例,我们只需要设置正确的响应类型,然后获取PrintWriter
,写入响应即可。
而这样的一个项目最终会打包成一个*.war
文件,运行这个文件,需要使用支持Servlet
API
的Web容器(Web服务器)。
因此,我们首先要找一个支持Servlet API的Web服务器。
常用的服务器有:
- Tomcat:由Apache开发的开源免费服务器;
- Jetty:由Eclipse开发的开源免费服务器;
- GlassFish:一个开源的全功能JavaEE服务器。
Servlet的生命周期
在通过一个URL
路径发起对一个Servlet
请求的过程中,其本质是在调用执行Servlet
实例的doXXX()
方法。该Servlet
实例创建和使用的过程,被称为Servlet的生命周期。整个生命周期包括:实例化、初始化、服务、销毁。
- 实例化:根据
Servlet
请求的路径(例如:home.do
),查找该Servlet
的实例。如果实例不存在,则通过调用构造方法,完成Servlet
实例的创建。 - 初始化:通过该
Servlet
的实例,调用init()
方法,执行初始化的逻辑。 - 服务:通过该
Servlet
的实例,调用service()
方法,如果子类没有重写该方法,则调用HttpServlet父类的service()
方法,在父类的该方法中进行请求方式的判断,如果是GET
请求,则调用doGet()
方法;如果是POST
请求,则调用doPost()
方法;
如果子类重写doXXX()
方法,则调用子类重写后的doXXX()
方法;
如果子类没有重写doXXX()
方法,则调用父类的doXXX()
方法,在父类的方法实现中,返回一个405
状态码的错误页面。
405状态码:代表请求的方式服务器不提供支持。
4.销毁:服务器关闭或重启时,会销毁所有的Servlet实例,会调用Servlet实例的destroy()
方法。

- package com.my.hyz.web.servlet;
-
- import java.io.IOException;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- //@WebServlet("/home.do")
- public class HomeServlet extends HttpServlet {
-
- public HomeServlet() {
- System.out.println("实例化");
- }
- @Override
- public void init() throws ServletException {
- System.out.println("初始化");
- //super.init();
- }
-
- @Override
- protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("调用Service实例");
- }
-
- @Override
- public void destroy() {
- System.out.println("销毁咯!!!!");
- }
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // TODO Auto-generated method stub
- System.out.println("哎呦get到了"+this.hashCode());
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("哎呦post到了");
- }
- }

到此这篇关于Java中Servlet的生命周期详解的文章就介绍到这了,更多相关Java Servlet 生命周期内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!