1. Servlet概述
Servlet是一个运行在服务器端的java小程序,通过Http协议用于接收客户端的请求,并发出响应。Servlet是JavaWeb三大组件之一,也是最重要的组件!三大组件:Servlet、Filter、Listener。
2. Servlet入门
(1)编写一个java类,实现servlet接口
(2)修改web.xml文件,给servlet提供一个可访问的URI地址
(3)将应用部署到tomcat服务器
(4)测试:http://localhost:8080/Servlet/ss
3. Servlet执行过程
4. Servlet生命周期
实例化-->初始化-->服务-->销毁
出生:(实例化-->初始化)第一次访问Servlet就出生(默认情况下)
活着:(服务)应用活着,servlet就活着
死亡:(销毁)应用卸载了servlet就销毁。
Servlet接口中一共是5个方法,其中有三个是生命周期方法。
void init(ServletConfig):这个方法会在Servlet被创建后,马上被调用。只会被调用一次!我们可以把一些初始化工作放到 这个方法中,如果没有什么初始化工作要做,那么这个方法就空着就可以了。【Servlet有两个时 间点会被创建:一是在第一次被请求时,会被创建;二是Tomcat启动时被创建,默认是第一种, 如果希望在tomcat启动时创建,这需要在web.xml中配置。】
void destroy():这个方法会在Servlet被销毁之前被调用。如果你有一些需要释放的资源,可以在这个方法中完成,如果没有 那么就让这个方法空着。这个方法也只会被调用一次!【Servlet轻易不会被销毁,通常会在Tomcat关闭时 会被销毁。】
void service(ServletRequest,ServletResponse):它会在每次被请求时调用!这个方法会被调用0~N次。
String getServletInfo():它不是生命周期方法,也就是说它不会被tomcat调用。它可以由我们自己来调用,但我们一般也 不调用它!你可以返回一个对当前Servlet的说明性字符串。
Servlet ConfiggetServletConfig():这个方法返回的是ServletConfig,这个类型与init()方法的参数类型相同。它对应的是 web.xml中的配置信息,即<servlet>
4.1 Servlet映射路径( url-pattern配置)
创建servlet后,如果想要这个servlet可以被访问到,必须在web.xml文件中对其进行配置。在其中有一个<url-pattern>这个标签是用于确定访问servlet的路径。一个servlet可以被不同的路径映射,即多个不同配置可以映射同一个servlet.
对于<url-pattern>在开发中它的写法有以下几种:
完全匹配 要求必须以”/”开始
目录匹配 必须以”/”开始,以”*”结束
扩展名匹配 不能以”/”开始,以*.xxx结束 xxx代表的是后缀名
优先级完全匹配>目录匹配>扩展名匹配
注意:
1)url-pattern要么以 / 开头,要么以*开头。 例如ss是非法路径。
2)不能同时使用两种模糊匹配,例如 /ss/*.do是非法路径
3)当有输入的URL有多个servlet同时被匹配的情况下:
3.1 精确匹配优先。(长的最像优先被匹配)
3.2 以后缀名结尾的模糊url-pattern优先级最低!!!
4.2 Servlet缺省路径
servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。
根据URL读取文件的的原理 :URL输入http://localhost:8080/servlet001/index.html
1)到当前Servlet001应用下的web.xml文件查找是否有匹配的url-pattern。
2)如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理
3)DefaultServlet程序到day10应用的根目录下查找是存在一个名称为index.html的静态文件。
4)如果找到该文件,则读取该文件内容,返回给浏览器。
5)如果找不到该文件,则返回404错误页面。
总结:先找动态资源,再找静态资源。
4.3 Servlet自动加载
Servlet默认是第一次访问时候创建实例。通过配置,服务器启动,创建实例。init做初始化的操作,非常消耗时间的。
在<servlet>标签下配置
<load-on-startup>3</load-on-startup>
值是正整数,如果值越小,优先级越高。
5. Servlet的创建方式
(1)实现javax.servlet.Servlet接口
(2)继承javax.servlet.GenericServlet类(适配器模式)
(3)继承javax.servlet.http.HttpServlet类(模板方法设计模式)
Servlet -->GenericServlet-->HttpServlet-->(继承HttpServlet)
6. Servlet的线程安全问题
Servlet是单例的,一个servlet对象可能同时处理多个请求。所以当多个servlet线程同时访问servlet共享数据,如成员变量,可能会引发线程安全问题。解决办法:
a.把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)
b.在servlet类中尽量不要使用成员变量。如果非要使用成员变量,必须同步。而且尽量缩小同步代码块的范围。
7. Servlet接口
Servlet接口定义所有servlet 都必须实现的方法,包括初始化 servlet 的方法、为请求提供服务的方法和从服务器移除 servlet 的方法。这些方法称为生命周期方法,它们是按以下顺序调用的:
1.构造 servlet,然后使用 init 方法将其初始化。 2.处理来自客户端的对 service 方法的所有调用。 3.从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。 |
除了生命周期方法之外,此接口还提供了getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一种方法获得任何启动信息,而后一种方法允许 servlet 返回有关其自身的基本信息,比如作者、版本和版权。
8. GenericServletd类
GenericServlet是HttpServlet的父类,它也是一个抽象类,主要处理一般的,与协议无关的servlet,如果要编写关于http协议使用HttpServlet。
GenericServlet实现了一个Servlet接口,这个接口定义了所有的servlet都必须实现的方法。它代理了ServletConfig的所有功能。所有使用ServletConfig才能调用的方法,都可以使用GenericServlet的同名方法来完成!不能覆盖父类的init(ServltConfig)方法,因为在父类中该方法内完成了this.config=config,其他的所有ServletConfig的代理方法都使用this.config来完成的。一旦覆盖,那么this.config就是null。如果需要做初始化工作,那么可以去覆盖GenericServlet提供的init()方法。
9. HttpServlet类
Javax.servlet.http.HttpServlet类,是一个抽象类,它的作用是提供将要被子类以创建适用于web 站点的Http servlet的抽象类。而对于HttpServlet的子类,一般需要重写以下方法。
doGet,如果 servlet 支持 HTTP GET 请求 doPost,用于 HTTP POST 请求 init 和 destroy,用于管理 servlet 的生命周期内保存的资源 getServletInfo,servlet 使用它提供有关其自身的信息 |
在开发中一般重写doPost、doGet方法。
10. ServletConfig对象
10.1 ServletConfig概述
ServletConfig是javax.servlet包下的一个接口,它是由servlet容器(tomcat)创建,并封装了servlet相关配置信息的对象,并在servlet容器初始化期间传递给了servlet.,通过init(ServletConfigconfig)方法传递。
(1)作用
ServletConfig对象: 主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象 (一 个Servlet对应一个ServletConfig对象)
(2)对象的创建与获取
创建时机: 在创建完servlet对象之后,在调用init方法之前创建。
得到对象: 直接从有参数的init方法中得到
(3)servlet初始化参数设置
在web.xml文件中我们可以对servlet进行配置,在<servlet>配置标签内可以有以下这样的子标签
<init-param>
<param-name>参数名称</param-name>
<param-value>参数值</param-value>
</init-param>
(4)有参数init(ServletConfig config)与无参数init()方法关系:
有参数的init方法,是servlet接口中定义的。
而无参数的init方法是GenericServlet中定义的。
在GenericServlet中重写了有参数的init方法,并在其中调用了无参数的init方法。
那么,在创建一个servlet时,如果是继承了HttpServlet,在重写init方法时,就可以只重写无参数init就可以。
(5)ServletConfig主要作用有以下三个方面:
获取Servlet名称 getServletName()
获取Servlet初始化参数 getInitParameter() getInitParameterNames()
获取ServletContext对象
10.2 获取ServletConfig对象
在servlet中如果想要获取到ServletConfig对象,可以通过getServletConfig()对象来获取。这个方法是在javax.servlet.Servlet接口中定义的,在GenericServlet中对getServletConfig()方法进行了实现。代码如下:
ServletConfigconfig=this.getServletConfig();
10.3 ServletConfig常用方法
String getServletName()
获取在web应用程序中部署的servlet实例的名称(servletName中定义的)
String getInitParameter(Stringname)
获取指定初始化参数的值,如果不存在,返回null
Enumeration getInitParameterNames()
以 String 对象的Enumeration 的形式返回 servlet 的初始化参数的名称
ServletContext getServletContext()
返回对调用者在其中执行操作的ServletContext 的引用(获取servlet的管理者)。
11. ServletContext
11.1 ServletContext概述
ServletContext它是javax.servlet.包下的一个接口。WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。
获取 :context=this.getServletConfig().getServletContext();
在开发中可以通过以下方式获取
ServletContextcontext=this.getServletContext();
在getServletContext()方法内部也是通过ServletContextServletConfig获取的。
ServlectContext作用
获取全局初始化参数
实现servlet共享资源
获取web资源
其它操作
11.2 ServletContext获取初始化参数
在web.xml文件中有<context-param>标签可以设置全局初始化参数.
<context-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</context-param>
对于ServletContext对象它也提供了以下两个方法用于获取初始化参数
String getInitParameter(String name)
Enumeration getInitParameterNames()
11.3 ServletContext实现servlet共享
ServletContext对于一个web应用只有一个,所有的servlet使用的就是同一个ServletContext。
ServletContext提供以下方法用于在域中进行数据操作
Object getAttribute(String name)
返回具有给定名称的servlet 容器属性,如果不具有该名称的属性,则返回 null。
void setAttribute(String name,Object object)
将对象绑定到此servlet 上下文中的给定属性名称。如果已将指定名称用于某个属性,则此方法将使用新属性替换具有该名称的属性。
void removeAttribute(String name)
从 servlet 上下文中移除具有给定名称的属性。
11.4 ServletContext获取web中的资源
String getRealPath(String path)
为给定虚拟路径返回包含实际路径的 String(返回的路径到项目名称)
InputStream getResourceAsStream(String path)
以 InputStream对象的形式返回位于指定路径上的资源。
String getMimeType(String file) 可以获取一个文件的mimeType类型.
URL getResource(String path) 它返回的是一个资源的URL
还提供log(String msg),getRequestDispatcher(String path) 等这样的方法,可以做日志与转向操作
12. Classpath
java project----所有class都在bin目录下
web project-----所有的class都在classes目录下
12.1 Class获取
Class.getResource("/").getPath();获取classes目录的绝对磁盘路径
Class.getResource("").getPath();获取的是当前Class对象代表的类所在的包的路径。
12.2 ClassLoader获取
Class.getClassLoader().getResource("/").getPath();
获取的是classes目录的绝对磁盘路径
Class.getClassLoader().getResource("").getPath();
获取的是classes目录的绝对磁盘路径
这两个getResource()是使用当前ClassLoader加载资源(即资源在 Classpath中),这样资源和class直接打在jar包中,避免文件路径问题.两者不同是Class的getResource()方法是从当前.class 文件路径查找资源,ClassLoader则是从jar包根目录查找.。
总结:
ServletRequest:封装了请求信息;
ServletResposne:用于向客户端响应;
ServletContext:它可以在多个Servlet中共享数据。
ServletConfig:它与<servlet>对应!
在<servlet>中可以配置<init-param>,即初始化参数,可以使用ServletConfig的getInitParameter(String),方法的参数是初始化参数名,方法的返回值是初始化参数值。
getInitParameterNames(),该方法返回一个Enumeration对象,即返回所有初始化参数的名称。
String getServletName(),它返回的是<servlet-name>元素的值
ServletContext getServletContext(),它可以获取Servlet上下文对象。