概述

是一个部署于web服务器中的实现了servlet接口的Java类,用于响应web请求

Web容器(也称为servlet容器)本质上是与servlet交互的Web服务器的组件。Web容器负责管理servlet的生命周期,将URL映射到特定的servlet,并确保URL请求者具有正确的访问权限。

和CGI相比更有性能优势

流程

  1. 假设用户请求访问URL

    1. 浏览器为此URL生成HTTP请求。
    2. 将此请求发送到适当的服务器。
  2. HTTP请求由Web服务器接收并转发到servlet容器。
    1. 容器将此请求映射到特定的servlet。
    2. 动态检索servlet并将其加载到容器的地址空间中。
  3. 容器调用servlet 的init()方法。
    1. 仅当servlet首次加载到内存中时才会调用此方法。
    2. 可以将初始化参数传递给servlet,以便它可以自行配置。
  4. 容器调用servlet 的service()方法。
    1. 调用此方法来处理HTTP请求。
    2. servlet可以读取HTTP请求中提供的数据。
    3. servlet还可以为客户端制定HTTP响应。
  5. servlet保留在容器的地址空间中,可用于处理从客户端收到的任何其他HTTP请求。
    1. 每个HTTP请求都会调用service()方法。
    2. 每个请求都在自己独立的线程中提供服务。
    3. Web容器为每个请求调用servlet 的service()方法。该service()方法确定正在进行的请求的类型,并将其分派给适当的方法来处理请求。servlet的开发人员必须为这些方法提供实现。如果对servlet未实现的方法发出请求,则调用父类的方法,通常会导致将错误返回给请求者。
    4. service()方法有参数:
      1. ServletRequest req:从容器接收的请求数据
      2. ServletResponse res:返回给容器的响应数据
  6. 在某些时候,容器可能决定从其内存中卸载servlet。
    1. 做出此决定的算法特定于每个容器。
  7. 容器调用servlet的destroy()方法来放弃任何资源,例如为servlet分配的文件句柄; 重要数据可以保存到持久性存储中。
  8. 然后可以对为servlet及其对象分配的内存进行垃圾回收。

两个已经实现好的servlet抽象类

GenericServlet

  • 实现了Servlet接口
  • GenericServlet是独立于协议的,可以在J2EE应用程序中用于实现从其他Java类访问的服务

HttpServlet

  • 继承自GenericServlet
  • 用于实现适用于web站点的HTTP servlet
  • 其子类必须实现至少一种以下方法:
    • doGet, if the servlet supports HTTP GET requests
    • doPost, for HTTP POST requests
    • doPut, for HTTP PUT requests
    • doDelete, for HTTP DELETE requests
    • init and destroy, to manage resources that are held for the life of the servlet
    • getServletInfo, which the servlet uses to provide information about itself
  • 重写Service方法是没有必要的,因为已经实现的功能是将标准的HTTP请求根据HTTP请求的类型分发给相应的doXXX方法
  • 标准的Servlet的Service方法的参数是ServletRequest/ServletResponse类型。HttpServlet也有这个方法,但是这个方法会将请求发送给另一个protected的service方法,这个方法的参数是HttpServletRequest/HttpServletResponse类型的

将servlet配置为web应用程序的一部分

在Web应用程序部署描述符(Web.xml)中用<servlet>和<servlet-mapping>将servlet部署为应用程序的一部分

<servlet>:

  • <servlet-name>:定义servlet的名字
  • <servlet-class>:定义执行servlet的已编译类
  • <init-param>:定义初始化属性,这些属性的使用将在ServletConfig中描述
    • <param-name>:变量名
    • <param-value>:变量值
  • <load-on-startup>1<load-on-startup>:可选,如果存在,将在应用程序启动的时候加载servlet并调用其inti方法;若不存在,则在该servlet的第一个请求时加载它

<servlet-mapping>:控制访问servlet的方式

  • <servlet-name>:Servlet的注册名称,可以在多个<servlet-mapping>中相同
  • <url-pattern>:Servlet的对外访问路径

配置JSP:将JSP注册为Servlet

  • JSP也是一种servlet
  • 在第一次调用JSP的时候会按照JSP的名称隐式注册JSP
  • 也可以在Web.xml文件中按照servlet的方式注册:
<servlet>
     <servlet-name>myFoo</servlet-name>
     <jsp-file>myJSPfile.jsp</jsp-file>
</servlet>
<servlet-mapping>
     <servlet-name>myFoo</servlet-name>
     <url-pattern>/main</url-pattern>
</servlet-mapping>

初始化参数的传递——ServletConfig

  • Servlet config对象是servlet容器用于在servlet的初始化期间向servlet发送信息
  • Web容器将会把配置的初始化参数封装到ServletConfig对象中,servlet接口中的init方法会有ServletConfig参数,Web容器将会把封装好的ServletConfig对象发送给init作为参数,这样servlet就可以获取配置的初始化参数
  • 方法
    • getInitParameterNames:以字符串的枚举方式返回配置的所有初始化参数名
    • getInitParameter(String name):按照参数名name返回参数值

将请求映射到servlet

URL:

使用以下模式构造客户端用于访问Web应用程序的URL(UTF-8解码):

http:// hoststring/ ContextPath/ servletPath/pathInfo

  • Hoststring:是映射到虚拟主机的主机名或hostname:portNumber。
  • pathInfo:URL的剩余部分,比如文件名
  • servletPath:代表一个映射到servletPath 的servlet
  • ContextPath:Web应用程序名称

Web容器在接收到客户端请求后将决定要转发给哪一个Servlet,所选择的Servlet的Context Path具有和URL的最长匹配

所使用的匹配到servlet的路径是URL减去context path和path parameters,即servletPath

将按照以下规则顺序匹配,一旦匹配成功将终止

  • 容器将尝试查找请求路径与servlet路径的完全匹配
  • 容器将递归地尝试匹配最长的路径前缀。 这是通过使用'/'字符作为路径分隔符,一次步进路径树(所有的servlet的路径构成的,叶节点作为一个servlet)的一个目录来完成的。 最长匹配确定所选的servlet。
  • 如果URL路径中的最后一个段包含扩展名(例如.jsp),则servlet容器将尝试匹配可以处理扩展请求的servlet。 扩展名定义为最后一个字符后的最后一个段的一部分。
  • 如果前三个规则都不会导致servlet匹配,则容器将尝试提供适合所请求资源的内容。如果为应用程序定义了默认servlet,则将使用它。许多容器提供用于提供内容的隐式默认servlet。

容器进行匹配时区分大小写

在Web应用程序的部署描述符中(<url-pattern>),下列语法将用于定义匹配

  • 以’/’开头且以’/*’结尾的字符串将用于路径匹配
  • 以’*.’开头的字符串将用于扩展名匹配
  • 空字符串是对应用程序的context root的完全匹配,即匹配到http://host:port/<context-root>/
  • ‘/’字符串表示这是web应用的默认servlet
  • 所有其他类型的字符串将用于完全匹配

如果有效的web.xml(在从片段和注释合并信息之后)包含映射到多个servlet的任何url模式,则部署必将失败。

  • 实验:在将两个servlet配置了部分相同的url pattern之后运行tomcat,在显式的信息中有:
  • x月 xx, 20xx x:xx:x x午 org.apache.catalina.core.ContainerBase addChildInternal
    严重: ContainerBase.addChild: start:
    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/SpringDemo02]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1017)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:993)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1296)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2039)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:844)
    Caused by: java.lang.IllegalArgumentException: The servlets named [DefaultServlet] and [ControllerServlet] are both mapped to the url-pattern [/product_input] which is not permitted
    at org.apache.catalina.deploy.WebXml.addServletMapping(WebXml.java:293)
    at org.apache.catalina.startup.ContextConfig.processAnnotationWebServlet(ContextConfig.java:2448)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2123)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsJndi(ContextConfig.java:2039)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1934)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1303)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:878)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:388)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5566)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    ... 10 more

隐式映射:如果容器具有内部JSP容器,则* .jsp扩展名将映射到它,从而允许按需执行JSP页面。该映射称为隐式映射。 如果Web应用程序定义了* .jsp映射,则其映射优先于隐式映射

Java Web Application——servlet的更多相关文章

  1. 使用Intellij idea新建Java Web项目(servlet) 原理及初步使用

    准备 JDK       (配置JDK_HOME\bin   和 CLASSPATH)   注:JDK8下载已经需要注册了,请使用JDK11(现在是官方长期支持的版本)     对于我们新手来说,JD ...

  2. ThreadLocal Memory Leak in Java web application - Tomcat

    ThreadLocal variables are infamous for creating memory leaks. A memory leak in Java is amount of mem ...

  3. Java Web之Servlet中response、request乱码问题解决

    Java Web之Servlet中response.request乱码问题解决   一.request请求参数出现的乱码问题 get请求: get请求的参数是在url后面提交过来的,也就是在请求行中, ...

  4. java web中servlet、jsp、html 互相访问的路径问题

    java web中servlet.jsp.html 互相访问的路径问题 在java web种经常出现 404找不到网页的错误,究其原因,一般是访问的路径不对. java web中的路径使用按我的分法可 ...

  5. JAVA WEB 用servlet实现分页,思路比较清晰和简单。

    JAVA WEB 用servlet实现分页,思路比较清晰和简单.借鉴了其他大佬的思路.特别感谢. 是我第一次发表博客,如果有什么错误,欢迎大家指出!,谢谢 一.思路分析 前台一定是有类似这种的界面 点 ...

  6. Java Web Application使Session永不失效(利用cookie隐藏登录)

    在做 Web Application 时,因为 Web Project 有 session 自动失效的问题,所以如何让用户登录一次系统就能长时间运行三个月,就是个问题. 后来,看到 session 失 ...

  7. java攻城师之路--复习java web之servlet

    需要掌握的知识点:1.Servlet程序编写 ----- 生命周期2.ServletAPI Request Response 3.Cookie 和 Session Servlet 用来 动态web资源 ...

  8. Java Web之Servlet技术

    1.Servlet基础 针对Servlet技术开发,Sun公司提供了一些列接口和类,其中最重要的是javax.servlet.Servlet接口,两个重要的包是javax.servlet和javax. ...

  9. Java Web之Servlet

    Servlet参考文献: 1.http://www.cnblogs.com/luoxn28/p/5460073.html 2.http://www.cnblogs.com/xdp-gacl/p/376 ...

随机推荐

  1. css文字换行问题white-space:pre-line或者white-space:pre-wrap,解决word-wrap:break-word解决不了的

    想让文字换行必须要写的那几个css样式就略过了.当一行文字是数字或字母时或者数字字母组合时会出现不换行局面,这时候加个word-wrap:break-word:就基本可以解决但是有种情况是它解决不了的 ...

  2. Excel中将字符串中从右起第n个指定字符替换的方法

    比如你想把www.baidu.com.cn中的倒数第二个”.”替换成@,则可以用: =SUBSTITUTE(A1,".","@",LEN(A1)-LEN(SUB ...

  3. transient修饰符的作用

    transient修饰符的作用: entity实体类: package com.baidu.entity; import com.fasterxml.jackson.annotation.JsonIg ...

  4. Android 对话框黑色边框的解决

    代码解决 : Dialog dialog = new Dialog(this); Window win = dialog.getWindow(); win.setBackgroundDrawableR ...

  5. 51nod 1632 B君的连通

    题目: 这题看起来难,其实这么多概率啥的都是唬人的.甚至连快速幂都不用就可以解. 解法:    n个节点,n-1条边,期望会有一半的边被炸毁(因为总体概率就是50%). 即(n-1)/2条边被炸毁,这 ...

  6. Base64就是一种 基于64个可打印字符来表示二进制数据的表示方法

    Base64编码是从二进制到字符的过程. Base64编码主要用在传输.存储.表示二进制等领域,还可以用来加密,但是这种加密比较简单. byte[] byteArray = Encoding.UTF8 ...

  7. C++ 获取某一文件夹下的所有文件名

    //********************************************************************** // Method: 获取文件夹下所有文件 // Fu ...

  8. 《Unix环境高级编程》读书笔记 第11章-线程

    1. 引言 了解如何使用多个控制线程在单进程环境中执行多个任务. 不管在什么情况下,只要单个资源需要在多个用户键共享,就必须处理一致性问题. 2. 线程概念 典型的Unix进程可以看成只有一个控制线程 ...

  9. NetworkX-根据权重画图

    load_data = sio.loadmat(load_path) #阈值处理 mat=np.array(load_data['R']) mat[mat<0]=0 mat[mat<0.4 ...

  10. vuecli的使用之项目中的文件

    cli创建的项目截图 node_moudule :下载的依赖包的存储位置. public :html的地方??? src :写代码的地方 man.js :入口文件 .browserslistrc :浏 ...