一、引入Servlet
要编写一个完善的 HTTP 服务器,以 HTTP/1.1 为例,需要考虑的包括:
识别正确和错误的 HTTP 请求;
识别正确和错误的 HTTP 头;
复用 TCP 连接;
复用线程;
IO 异常处理;
这些基础工作需要**耗费大量的时间**,并且经过长期测试才能稳定运行。如果我们只需要输出一个简单的 HTML 页面,就**不得不编写上千行底层代码**,那就根本**无法做到高效而可靠地开发**。 因此,在 JavaEE 平台上,处理 TCP 连接,解析 HTTP 协议这些底层工作统统扔给现成的 Web 服务器去做,我们只需要把自己的应用程序跑在 Web 服务器上。为了实现这一目的, JavaEE 提供了 **Servlet API** ,我们使用 Servlet API 编写自己 的 Servlet 来处理 HTTP 请求, Web 服务器实现 Servlet API 接口,实现底层功能,在这我选择的服务器是Tomcat:由Apache开发的开源免费服务器。 先来实现一个简单的Servlet:
// HelloServlet继承HttpServlet
// 处理HTTP协议的请求,并按照HTTP协议进行响应
@WebServlet("/hello.do")
public class HelloServlet extends HttpServlet{
//重写doGet方法:处理get方式的请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("哎呀,被get到了");
}
}
注意:所有的请求路径必须以“/”开头
在浏览器输入 http://localhost:8080/项目名称/hello.do ,即可看到 HelloServlet 的输出。 为什么路径是 "/项目名称" 而不是 / ?因为一个 Web 服务器允许同时运行多个 Web App 。因此,第一级目录 /项目名称表示Web App的名字,后面的 /hello.do 才是我 们在 HelloServlet 中映射的路径。
二、浅析Servlet
浏览器发送请求的时候,还会有请求方法( HTTP Method ):即GET 、POST 、PUT 等不同类型的 请求。因此,要处理GET请求,我们要覆写 doGet() 方法;要处理POST请求,就需要覆写 doPost() 方法。如果没有覆写 doPost() 方法,那么 HelloServlet 能不能处理POST请求方式下的 /hello.do 请求呢? 我们查看一下 HttpServlet 的 doPost() 方法就一目了然了:它会直接返回 405 或 400 错误。
400 Bad Request:表示客户端发送了一个错误的请求,例如参数无效;
405 Method Not Allowed:代表请求的方式服务器不提供支持,不允许的方法
三、Servlet生命周期
在通过一个 URL 路径**发起对一个 Servlet 请求**的过程中,其**本质是在调用执行 Servlet 实例的 doXXX() 方法**。该 Servlet 实例创建和使用的过程,被称为Servlet 的生命周期。整个生命周期包括:实例化、初始化、服务、销毁。
@WebServlet("/home.do")
public class HomeServlet extends HttpServlet
1 实例化:根据 Servlet 请求的路径(例如: home.do ),查找该 Servlet 的实例。如果实例不存在,则通过调用构造方法,完成 Servlet 实例的创建。
public HomeServlet() {
System.out.println("1.HomeServlet实例被创建");
}
2 初始化:通过该 Servlet 的实例,调用 init() 方法,执行初始化的逻辑。
@Override
public void init() throws ServletException {
System.out.println("2.HomeServlet实例初始化");
}
3 服务:通过该 Servlet 的实例,调用 service() 方法,如果子类没有重写该方法,则调用HttpServlet父类的 service() 方法,在父类的该方法中进行请求方式的判断,如果是GET请求,则调用 doGet() 方法;如果是 POST请求,则调用 doPost() 方法; 如果子类重写 doXXX() 方法,则调用子类重写后的 doXXX() 方法; 如果子类没有重写 doXXX() 方法,则调用父类的 doXXX() 方法,在父类的方法实现中,返回一个 405 状态码的错误页面。
4 销毁:服务器关闭或重启时,会销毁所有的Servlet实例,会调用Servlet实例的 destroy() 方法。
@Override
public void destroy() {
System.out.println("4.HomeServlet实例被销毁");
}
小结:
Servlet生命周期顾名思义就是从servlet出现到消亡(销毁)的全过程。
主要分为以下几个阶段:
加载类—>**实例化(**为对象分配空间)—>初始化(为对象的属性赋值)—>请求响应(服务阶段)—>销毁
以上就是对于Servlet生命周期的分享,如有不当之处还请大家多多评论指正,喜欢文章的可以留下您的关注和点赞,一起学习,一起加油!
版权归原作者 m.j.y. 所有, 如有侵权,请联系我们删除。