一、前言

现如今流行的web服务器如tomcat,既可以是HTTP服务器(处理静态资源,当性能比不上Nginx等专业),也可以是一个web容器,web容器就是一个servlet容器,而servlet容器就是实现了servletAPI规范的一组服务。

Servlet API规范中,定义了其生命周期的三个方法:init(),service(),destroy(),还有过滤器filter,监听器listener。这些servletAPI规范定义在javax.servlet-api包中,它是单独一个java包,需要下载才能使用。

而servlet容器实现了这些servlet API规范,负责servlet的创建、执行和销毁。

二、Servlet

上面说到servlet,那么什么是servlet呢?为什么需要servlet呢?

servlet就是一个java应用程序,实现了servletAPI规范的java应用程序就是一个servlet,主要是用来处理来自web浏览器或者其他HTTP客户端的请求,常常跟我们的业务程序或者我们的数据对接,相当于一个中间层的作用,动态地生成内容给服务器;要部署和运行servlet,需要使用web容器(servlet容器),web容器本质上就是与servlet交互的web服务器组件,web容器负责管理servlet的生命周期,将URL映射到特定的servlet(具体在web.xml中配置)并确保URL请求者具有正确的权限。如下图:

servlet应用程序主要的任务就是

  • 读取Web服务器(如tomcat)发送过来的数据(表单数据、HTTP请求数据-cookie等)
  • 处理接收到的数据,可能调用其他业务服务或者直接访问数据库,生成需要的响应结果
  • 将指定格式的响应结果返回给Web服务器(文本文件、二进制文件、Excel、cookie参数等)。

如何创建这个servlet应用程序呢

  • 首先,需要使用servletAPI提供的jar包,也就是遵循servlet规范来开发servlet应用程序,使用servletAPI包有两种方式:

    • 1.使用JDK版本为SE标准版,则需要下载并依赖引入servlet-api包(具体方式可是通过maven的pom.xml依赖引入等)
    • 2.使用JDK版本为EE企业版,则不需下载,直接引用rt.jar下的servlet-api包即可
  • 然后,创建servlet应用程序,有三种方式:
    • 1.创建一个servlet实现类,直接实现javax.servlet-api包下的Servlet接口,并重写实现接口的所有方法:

      • init(ServletConfigservletConfig):servlet初始化时只执行一次。
      • service(ServletRequestservletRequest,ServletResponseservletResponse):servlet处理请求时执行。
      • getServletConfig():运行时,获取servlet初始化和启动的相关参数。
      • getServletInfo():运行时,获取运行servlet应用程序的相关信息,如作者,版本等。
      • destroy():servlet停止的时候执行。
    • 2.创建一个子类,继承GenericServlet抽象类;该类也是实现类Servlet接口,只不过也实现了ServletConfig接口,并提供获取getServletName()、getServletContext()、getInitParameterNames()等方法,必须需要自己重写实现的方法就是service()方法,简化了开发Servlet,只关注我们自己的业务服务即可。
    • 3.创建一个子类,继承HttpServlet抽象类;该类继承了GenericServlet抽象类,在其基础上进一步拓展HTTP的内容,但是不需要重写任何方法,HttpServlet类已经帮我们完成重写,我们可以选择覆盖它重写的方法。该类增加了在Servlet处理HTTP请求时根据方法划分的doGet(),doHead(),doPost(),doPut(),doDelete(),doOptions(),doTrace()等主要方法,在service()方法中根据HTTP请求方法来调用,这也就是该类叫HttpServlet的原因了。
  • 再然后(可选),可以编写一些过滤器Filter,主要用于我们可以动态拦截HTTP请求及HTTP响应,原理就是Servlet容器将这些过滤器实例一并纳入Servlet实例的生命周期中,当Servlet实例在运行时,在web.xml中配置了过滤器,会在servlet实例执行service()方法之前先调用filter实例的doFilter()方法,doFilter()方法中的FilterChain对象确定是否继续执行servlet实例的service()方法,FilterChain对象是一个filter链,也有一个doFilter()方法,在上一个filter实例中调用了FilterChain.doFilter方法,下一个Filter实例的doFilter()方法才会执行,到了最后一个 Filter.doFilter 方法中调用的 FilterChain.doFilter 方法就会激活 Servlet实例的service 方法,如果在任何一个Filter.doFilter 方法中没有调用FilterChain.doFilter方法,则不会调用servlet的service()方法,这就起到了过滤的作用;总的来说就是Servlet容器将多个Filter实例组合成一个Filter链,来控制对servlet实例的过滤作用。具体使用:
    • 1.创建一个子类,实现servlet-api下的Filter接口,并重写其中的三个方法:过滤器实例化时只执行一次的初始方法init(),过滤器实例运行时每次请求都会执行的过滤方法doFilter(),过滤器实例从Servlet容器移除之前执行的销毁方法destroy()。或者继承GenericFilter,HttpFilter抽象类,与编写servlet实例一样。
    • 2.在Servlet容器的web.xml中配置该过滤器映射,使用<filter>标签指定过滤器,使用<filter-mapping>拦截请求强行执行指定的过滤器doFilter()方法。
    • 3.若使用多个过滤器,则实现多个Filter子类,在web.xml中配置多个过滤器实例,若存在过滤条件相同的多个过滤器,其执行顺序就按在web.xml配置<filter-mapping>的顺序先后执行。
  • 最后,就是处理这些HTTP请求了,我们处理的业务逻辑都是分布在service方法里面,HTTP服务器发送的请求会帮我们创建两个重要的实例:ServletRequest(经常使用其子类HttpServletRequest)和ServletResponse(经常使用其子类HttpServletResponse)
    • 1.先利用HttpServletRequest实例调用其方法(具体方法参考该接口的方法),获取HTTP请求头信息及body内容
    • 2.进一步调用自己的业务逻辑去处理这些请求
    • 3.最后将处理的结果数据,封装到HttpServletResponse实例中(具体方法参考该接口的方法)并想用返回。
  • 最最后(可选),Servlet的异常处理,当抛出异常的时候,我们可以自定义一个Servlet程序去单独处理这些异常并在web.xml中配置使用即可。

注意:上面中需要在web.xml中配置的Servlet,Filter,initParam等,都可以在servlet-api下annotation包中找到相应的注解,可以直接使用之间完成在web.xml的配置,省去很多麻烦。

如何运行Servlet应用程序(生命周期)

上面已经创建好servlet应用程序了,根据上面应用图,我们需要一个HTTP服务器,例如tomcat服务器,这个tomcat的使用后面再讲,这里只需要注意一点就是,如何你的运行环境使用的JDK版本是SE标准版本,需要将javax.servlet-api包配置到系统的CLASSPATH环境变量中,不然你的servlet应用程序将无法编译,如果使用的是JDK版本是EE企业版本则不需要,该版本包含了servlet的包。运行时的示例图(生命周期):

注意:servlet实例的生命周期是由Servlet容器控制,并不是完成一次请求处理的线程来控制的;init()方法在servlet实例创建的时候只完成一次,当处理HTTP请求的线程完成任务时,只是service()方法执行完了,destroy()方法并不会执行,由Servlet容器控制。

生命周期具体流程:

  • 1.用户请求访问指定URL

    • 浏览器为此URL生成HTTP请求
    • 浏览器将该HTTP请求发送到相应的web服务器
  • 2.HTTP请求由web服务器接收并转发到servlet容器
    • Servlet容器创建一个线程处理该HTTP请求
    • servlet容器将此HTTP请求解析并映射到特定的servlet
    • servlet被动态检索并加载到容器的地址空间中,开始创建servlet实例
  • 3.容器调用servlet的init()方法
    • 仅当servlet实例首次被创建并加载到内存时,才会调用此方法
    • 可以将自定义的初始化参数传递给该方法,以便可以自定义servlet配置
  • 4.容器调用Servlet的service()方法
    • 调用此方法处理HTTP请求
    • servlet可以读取HTTP请求中提供的数据
    • servlet还可以为客户端指定HTTP响应
  • 5.生成的servlet实例会继续保留在容器的地址空间中,并用于处理从客户端收到的任何其他HTTP请求
    • 后面的每次处理HTTP请求都是直接调用service()方法
  • 6.容器可以基于算法,如servlet实例空闲过多,会将一些servlet实例从内存中卸载
  • 7.容器会调用servlet实例的destroy()方法,servlet实例被清理前的方法处理。
  • 8.最后该servlet实例会被GC清理。

Servlet的应用发展历史

  • 浏览器的B/S模式飞速发展,出现了名为applet的浏览器java插件
  • 由于浏览器的限制,applet放在浏览器上的java插件也收到诸多限制于不便
  • 于是servlet出现了,被称为service端的applet,因此称之为servlet
  • 后来SUN公司发现Servlet编程非常繁琐,存在大量冗余代码,且在Servlet中嵌入前端代码,导致前端页面风格实现非常苦难
  • 之后,SUN借鉴了微软的ASP,引入JSP,前端jsp页面中嵌入后端代码,后端开发人员需要在前端页面中写servlet代码,出现了JSP时代
  • 后来Servlet引入了MVC思想,诞生了JSP+servlet+javaBean的模式
    • JSP(V):将后端代码封装在标签中,使用大量的标签,JSP只用来写前端代码而不要有后端代码
    • Servlet(C):Servlet完成Controller的功能再加上部分代码逻辑
    • JavaBean(M):Servlet将数据发送给Model,对model进行封装逻辑处理,最后将Model数据加载渲染到JSP上。
  • 之后,出现了一些MVC框架:Struts2,SpringMVC等
  • 最后基本就只剩下Spring MVC框架稳定下来,还有继续使用。
  • 最最后Springboot等框架直接将servlet给雪藏了,直接内嵌Servlet容器(如Tomcat,jetty,undertow),只需开发SpringBoot应用即可,就是今天所说的微服务。
  • 因此,总的来说,Servlet虽然现在都“看不到”其曾经的身影了,但是还是一直被使用着,servlet是web开发基础的基础,只是被各大框架给封装“雪藏”了。

详谈如今的Servlet相关推荐

  1. 详谈jsp和servlet的区别

    其实说白了JSP和SERVLET到底什么区别呢,JSP就象宾馆前台的服务员,要长的不错,让顾客一看就觉得比较舒服,他主要就是负责显示这个宾馆的形象的.而SERVLET就象部门经理,要处理各种各样的业务 ...

  2. JSP、Servlet和Spring MVC

    今年刚接触JavaWeb的时候碰巧认识了一帮老师做后端的哥们,我俩平时用的最多的也都是Java. 我:"老哥,我想给我那个项目做一个服务器应用程序,怎么搞啊" 老哥:"S ...

  3. Servlet过滤器概念特点等详谈

    一.Servlet过滤器的概念: ◆Servlet过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改. ◆Servlet过滤器本身并不产生请 ...

  4. Servlet 3.0 新特性概述

    Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...

  5. Servlet 3.0 新特性详解

    https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE ...

  6. 解决Tomcat下IntelliJ IDEA报错java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener

    解决Tomcat下IntelliJ IDEA报错java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener   笔者在做代 ...

  7. filter与servlet对照

            最近在开java物自,还记得刚开始使用servlet这是一个调试ajax什么时候,然后,我不知道怎么用,你知道写的路径来调用,总是提示404错,,到最后自己一点点的调通了,知道serv ...

  8. servlet异步_关于Servlet和异步Servlet

    servlet异步 Servlet API是Java EE标准的一部分,自1998年正式发布2.1规范以来,一直是基于Java的企业体系结构的重要组成部分. 它是一种自以为是的API,用于服务围绕一些 ...

  9. servlet异步_如何使用异步Servlet来提高性能

    servlet异步 这篇文章将描述一种性能优化技术,该技术适用于与现代Web应用程序相关的常见问题. 如今的应用程序不再只是被动地等待浏览器发起请求,而是希望自己开始通信. 一个典型的示例可能涉及聊天 ...

最新文章

  1. java正则表达式及api_JAVA常用API:正则表达式regular expression
  2. 脑机头条 第20期| 世界机器人大会-脑控打字创纪录
  3. 5G NGC — 会话管理模型 — 基于 Flow 的 QoS 模型
  4. dagride实现模糊查询
  5. [C++STL]map容器用法介绍
  6. android jni返回bitmap,JNI 层 Bitmap 转 OpenCV Mat
  7. Hadoop学习笔记(一):MapReduce工作机制
  8. 宝藏又小众的Digital Tutors视频教程素材网站分享
  9. java微信开发之--更换背景图片
  10. 2019年前端开发工作总结
  11. Flink DataStream的多流、键控流、窗口、连接、物理分区转换算子的使用
  12. argparse模块中的参数action、dest使用
  13. 沙滩啤酒win7主题【rmzt】
  14. 让闲置物品“换”出财富
  15. android 音乐文件删除,如何从华为手机恢复已删除的音频或音乐文件
  16. Android实习周记:第三周,工作里重复太多,觉得枯燥,怎么办?
  17. Ajax(跨域请求)
  18. vivado 时序例外约束
  19. 固态硬盘与普通硬盘的区别
  20. 电池工况测试 matlab,一种电动汽车用动力蓄电池脉冲工况测试方法与流程

热门文章

  1. 浅谈自恢复保险丝PTC最大工作电压的问题
  2. jetpack compose原理解析
  3. 计算机专业有必要数学竞赛吗,竞赛党必读,五大竞赛学科各有利弊,到底哪科最适合你呢...
  4. 高中化学竞赛能用计算机吗,高中生必看!五大竞赛学科各有利弊,到底哪科最适合你呢?...
  5. 全套医疗预约挂号小程序+管理后台Axure高保真原型
  6. Joker恶意软件的最新攻击技巧:使用Github隐藏有效载荷
  7. python中集合的定义以及如何创建集合
  8. AWIT DBackup 0.0.20 发布,备份系统
  9. 体积云渲染实战:ray marching,体积云与体积云光照
  10. J2EE开发常用架构及其性能