一、Servlet概述

1.1 什么是Servlet

  Servlet是sun公司提供一套规范(接口),是JavaWeb的三大组件之一(Servlet、Filter、Listener),它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:

  • 接收请求数据;
  • 处理请求;
  • 完成响应。

  例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理!Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。

1.2 Servlet的实现方式

  实现Servlet有三种方式:

  • 实现javax.servlet.Servlet接口;
  • 继承javax.servlet.GenericServlet类;
  • 继承javax.servlet.http.HttpServlet类;

  Servlet类由我们来写,通常我们会去继承HttpServlet类来完成我们的Servlet,但对象由服务器来创建,并且由服务器来调用相应的方法

1.3 Servlet的运行过程

  Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
  ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
  ②装载并创建该Servlet的一个实例对象。
  ③调用Servlet实例对象的init()方法。
  ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

  用户第一次访问Servlt的时候,服务器会创建一个Servlet的实例,Servlet中的init()方法就会执行。任何一次请求服务器都会创建一个新的线程访问Servlet中的service方法。在service方法内部根据请求方式的不同调用doXXX方法。(get请求调用doGet,post请求调用doPost)。当Servlet从服务器中移除掉,或者关闭服务器时,Servlet的实例就会被销毁,此时destroy方法就

二、Servlet的生命周期

  所谓xxx的生命周期,就是说xxx的出生、服务,以及死亡。Servlet生命周期也是如此!与Servlet的生命周期相关的方法有:

  • void init(ServletConfig);
  • void service(ServletRequest,ServletResponse);
  • void destroy();

2.1 Servlet的创建

  默认情况下,第一次访问servlet时服务器才会创建该对象,如果需要服务器启动时就创建Servlet,那么还需要在web.xml文件中配置:

<servlet>
<servlet-name>hello1</servlet-name>
<servlet-class>cn.itcast.servlet.Hello1Servlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>hello2</servlet-name>
<servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>hello3</servlet-name>
<servlet-class>cn.itcast.servlet.Hello3Servlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello3</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>

  在<servlet>元素中配置<load-on-startup>元素可以让服务器在启动时就创建该Servlet,其中<load-on-startup>元素的值必须是一个整数,表示servlet应该被载入的顺序,当值为0或者大于0时,表示容器在启动时就加载并初始化这个servlet;当值小于0或者没有指定时,则表示容器在该Servlet被请求时,才会去加载。正数的值越小,该Servlet的优先级就越高,应用启动时就优先加载。所以,<load-on-startuo>x</load-on-startuo>中x的取值1,2,3,4,5代表的是优先级,而非启动延迟时间。上例中,根据<load-on-startup>的值可以得知服务器创建Servlet的顺序为Hello1Servlet、Hello2Servlet、Hello3Servlet。通常大多数Servlet是在用户第一次请求的时候由应用服务器创建并初始化,但<load-on-startup>n</load-on-startup>   可以用来改变这种状况,根据自己需要改变加载的优先级!

  而且一个Servlet类型,服务器只创建一个实例对象,例如在我们首次访问http://localhost:8080/helloservlet/helloworld时,服务器通过“/helloworld”找到了绑定的Servlet名称为cn.itcast.servlet.HelloServlet,然后服务器查看这个类型的Servlet是否已经创建过,如果没有创建过,那么服务器才会通过反射来创建HelloServlet的实例。当我们再次访问http://localhost:8080/helloservlet/helloworld时,服务器就不会再次创建HelloServlet实例了,而是直接使用上次创建的实例。

因为一个类型的Servlet只有一个实例对象,那么就有可能会出现一个Servlet同时处理多个请求,那么Servlet是否为线程安全的呢?答案是:“不是线程安全的”。这说明Servlet的工作效率很高,但也存在线程安全问题!
所以我们不应该在Servlet中创建成员变量(可以创建局部变量),因为可能会存在一个线程对这个成员变量进行写操作,另一个线程对这个成员变量进行读操作

  在Servlet被创建后,服务器会马上调用Servlet的void init(ServletConfig)方法。请记住, Servlet出生后马上就会调用init()方法,而且一个Servlet的一生,这个方法只会被调用一次。这好比小孩子出生后马上就要去剪脐带一样,而且剪脐带一生只有一次。

  我们可以把一些对Servlet的初始化工作放到init方法中!

2.2 Servlet的服务

  当服务器每次接收到请求时,都会去调用Servlet的service()方法来处理请求。服务器接收到一次请求,就会调用service() 方法一次,所以service()方法是会被调用多次的。正因为如此,所以我们才需要把处理请求的代码写到service()方法中!

2.3 Servlet的销毁

  Servlet是不会轻易离去的,通常都是在服务器关闭时Servlet才会离去!在服务器被关闭时,服务器会去销毁Servlet,在销毁Servlet之前服务器会先去调用Servlet的destroy()方法,我们可以把Servlet的临终遗言放到destroy()方法中,例如对某些资源的释放等代码放到destroy()方法中。

三、Servlet的相关配置

3.1 基本配置

<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>com.itheima.servlet.QuickStratServlet</servlet-class>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql:///mydb</param-value>
</init-param>
<!--服务器启动时创建servlet-->
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/quickStratServlet</url-pattern>
</servlet-mapping>

3.2 url-pattern的配置方式

  <url-pattern>是<servlet-mapping>的子元素,用来指定Servlet的访问路径,即URL。它必须是以“/”开头

【完全匹配】:访问的资源与配置的资源完全相同才能访问到

<url-pattern>/quickStratServlet</url-pattern>

  可以在<servlet-mapping>中给出多个<url-pattern>,例如:

 <servlet-mapping>
<servlet-name>AServlet</servlet-name>
<url-pattern>/AServlet</url-pattern>
<url-pattern>/BServlet</url-pattern>
</servlet-mapping>

  那么这说明一个Servlet绑定了两个URL,无论访问/AServlet还是/BServlet,访问的都是AServlet。

【目录匹配】:格式:/虚拟的目录../*   *代表任意

<url-pattern>/servlet/* <url-patter>:/servlet/a、/servlet/b,都匹配/servlet/*;

【 扩展名匹配】:格式:*.扩展名

<url-pattern>*.do </url-pattern>:/abc/def/ghi.do、/a.do,都匹配*.do;

  注意:第二种与第三种不要混用,通配符要么为前缀,要么为后缀,不能出现在URL中间位置,也不能只有通配符。例如:/*.do就是错误的,因为星号出现在URL的中间位置上了。*.*也是不对的,因为一个URL中最多只能出现一个通配符。

【缺省路径】/

  通常情况访问html页面时,首先从当前web项目的web.xml文件寻找匹配路径,如果没有找到,再从tomcat默认的web.xml匹配,将使用缺省servlet

<servlet>
<servlet-name>hello1</servlet-name>
<servlet-class>cn.itcast.servlet.Hello1Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>/servlet/hello1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>hello2</servlet-name>
<servlet-class>cn.itcast.servlet.Hello2Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello2</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>

  tomcat获得匹配l路径时,优先级顺序:完全路径匹配>目录匹配>扩展名匹配

  当访问路径为http://localhost:8080/hello/servlet/hello1时,因为访问路径即匹配hello1的<url-pattern>,又匹配hello2的<url-pattern>,但因为hello1的<url-pattern>中没有通配符,所以优先匹配,即设置hello1。

四、ServletConfig对象

4.1 ServletConfig的作用

  ServletConfig对象是由服务器创建的,然后传递给Servlet的init()方法。ServletConfig对象对应web.xml文件中的<servlet>元素。例如你想获取当前Servlet在web.xml文件中的配置名,那么可以使用servletConfig.getServletName()方法获取!

  ServletConfig对象主要是用于加载servlet的初始化参数,它可以获取<servlet>中配置的<init-param>信息

  在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)

4.2 ServletConfig的API

  • String getServletName():获取Servlet在web.xml文件中的配置名称,即<servlet-name>指定的名称;

  • ServletContext getServletContext():用来获取ServletContext对象;

  • String getInitParameter(String name):用来获取在web.xml中配置的初始化参数,通过参数名<param-name>来获取参数<param-value>的值;

  • Enumeration getInitParameterNames():用来获取在web.xml中配置的所有初始化参数名称;

五、ServletContext对象

5.1 ServletContext概述

  一个项目只有一个ServletContext对象!我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据。

  WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用:  

  • ServletContext对象的创建是在服务器启动时完成的;

  • ServletContext对象的销毁是在服务器关闭时完成的。

  ServletContext对象的作用是在整个Web应用的动态资源之间共享数据!例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。ServletContext对象通常也被称之为context域对象。

5.2 获取ServletContext

  • 在Servlet中获取ServletContext对象:Servlet接口的void init(ServletConfig config)中:

    ServletContext context = config.getServletContext();,
  • 在GenericeServlet或HttpServlet中获取ServletContext对象:GenericServlet类有getServletContext()方法,所以可以直接使用this.getServletContext()来获取:
    ServletContext servletContext = this.getServletContext();

5.3 ServletContext的作用

【获得web应用全局的初始化参数】 

  Servlet也可以获取初始化参数,但它是局部的参数;也就是说,一个Servlet只能获取自己的初始化参数,不能获取别人的,即初始化参数只为一个Servlet准备!

  可以配置公共的初始化参数,为所有Servlet而用!这需要使用ServletContext才能使用!

  web.xml中配置初始化参数:

<context-param>
  <param-name>driver</param-name>
  <param-value>com.mysql.jdbc.Driver</param-value>
</context-param>

  通过context对象获得参数:

// 获得ServletContext对象
ServletContext context = this.getServletContext();
// 获得初始化参数
String initParameter = context.getInitParameter("driver");
System.out.println(initParameter);

【获得web应用中任何资源的绝对路径】

【在整个Web应用的动态资源之间共享数据】

  例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中获取这个值

【ServletContext是一个域对象】

  ServletContext是JavaWeb四大域对象之一(PageContext、ServletRequest、HttpSession、ServletContext)。

  域对象就是用来在多个Servlet中传递数据的,所有域对象都有存取数据的功能,因为域对象内部有一个Map,用来存储数据,下面是ServletContext对象用来操作数据的方法:

  • void setAttribute(String name, Object value):用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在ServletContext中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同;

  • Object getAttribute(String name):用来获取ServletContext中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)servletContext.getAttribute(“xxx”);,获取名为xxx的域属性;

  • void removeAttribute(String name):用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做;

  • Enumeration getAttributeNames():获取所有域属性的名称;

六、小案例——统计访问量

public class AServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取ServletContext对象
ServletContext context = this.getServletContext();
// 从ServletContext对象中获取名为count的属性
Integer count = (Integer) context.getAttribute("count");
if (count == null) {
// 如果不存在:说明是第一次访问,向Servletcontext中保存名为count的属性,值为1
context.setAttribute("count", 1);
} else {
// 如果存在:给访问量加1,然后再保存回去;
context.setAttribute("count", count + 1);
}
// 向浏览器输出
PrintWriter writer = response.getWriter();
writer.print("<h1>" + count + "</h1>");
}
}

JavaWeb学习笔记(三)—— Servlet的更多相关文章

  1. JavaWeb学习笔记三 Servlet

    Servlet 是运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过java的API,动态的向客户 ...

  2. JavaWeb学习笔记之Servlet(一)

    1. 引子: 当我们开始进入JavaWeb开发的学习时,我们就必须要和Servlet和HTTP这两个词进行打交道了,尤其是Servlet.即使到了后面使用JSP (我们知道JSP其本身就是一个Serv ...

  3. JavaWeb学习笔记:Servlet

    Servlet JavaWeb 概念 Java Web应用由一组Servlet.HTML页面.类.以及其他能够被绑定的资源构成. 他能够在各种供应商提供的实现Servlet规范的Servlet容器中执 ...

  4. JavaWeb学习笔记之Servlet(二)

    1.  GenericServlet 抽象类: 1). 是一个 Serlvet. 是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法 ...

  5. JavaWeb学习笔记总结 目录篇

    JavaWeb学习笔记一: XML解析 JavaWeb学习笔记二 Http协议和Tomcat服务器 JavaWeb学习笔记三 Servlet JavaWeb学习笔记四 request&resp ...

  6. javaweb学习笔记整理补课

    javaweb学习笔记整理补课 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务器端 * 在用户本地有一个客户端 ...

  7. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  8. Java学习笔记之---Servlet

    Java学习笔记之---Servlet (一)如何实现Servlet 1.实现javax.servlet.Servlet接口: 2.继承javax.servlet.GenericServlet类: 3 ...

  9. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  10. JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB

    JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...

随机推荐

  1. Unity抗锯齿的设置

    [Unity抗锯齿的设置] "Edit"->"Project Settings"->"Quality",可以质量设置Inspec ...

  2. libevent源码深度剖析六

    libevent源码深度剖析六 ——初见事件处理框架 张亮 前面已经对libevent的事件处理框架和event结构体做了描述,现在是时候剖析libevent对事件的详细处理流程了,本节将分析 lib ...

  3. 一个完整的用java客户端使用httpClient请求网页并返回的方法

    import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import ja ...

  4. jmeter 插件

  5. 张超超OC基础回顾01_类的创建,申明属性,以及本质

    一. 类的声明和实现&规则 1.如何编写类的声明 以@interface开头 , 以@end结尾, 然后再class name对应的地方写上 事物名称, 也就是类名即可 注意: 类名的首字符必 ...

  6. Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

    Spring框架找不到 applicationContext.xml文件,可能是由于applicationContext.xml文件的路径没有放在根目录下造成的

  7. 3.Dynamic Layout 动态布局。在槽中处理布局

    在应用程序中,一个界面的布局基本都是固定的. 在这个实例中,我们把管理布局的代码放在槽中.这样点击一次按钮,触发槽.布局改变一次.这样就成为一个动态布局. (一) 水平和竖直布局改变 横向: 纵向: ...

  8. 运行maven build报错No goals have been specified for this build.

    运行maven报错: [ERROR] No goals have been specified for this build. You must specify a valid lifecycle p ...

  9. Azure:Manage anonymous read access to containers and blobs

    Grant anonymous users permissions to containers and blobs By default, a container and any blobs with ...

  10. Examining Application Startup in ASP.NET 5

    By Steve Smith  June 23, 2015 ASP.NET 5 differs from previous versions of ASP.NET in many ways. Gone ...