JAVA WEB——Servlet详解(一)

一、什么是servlet?

       Servlet(服务器端小程序)是使用Java语言编写的服务器端程序,可以像JSP一样,生成动态的Web页。Servlet主要运行在服务器端,并由服务器调用执行,是一种按照Servlet标准开发的类。 Servlet程序是Java对CGI程序的实现,但是与传统CGI的多进程处理操作不同的是,Servlet采用了多线程的处理方式,这样就使得Servlet程序的运行效率比传统的CGI更高;而且Servlet还保留有Java的可移植性的特点,这样使得Servlet更易使用,功能也更加强大。

二、tomcat和servlet的关系

       Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件. Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品.

       Tomcat 的容器分为四个等级,Servlet 的容器管理 Context 容器,一个 Context 对应一个 Web 工程。Context 容器是直接管理 Servlet 在容器中的包装类 Wrapper,所以 Context 容器如何运行将直接影响 Servlet 的工作方式。

                                       

        tomcat加载Servlet有三种情况:
       1、Servlet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中的<Servlet></Servlet>之间添加如下代码:<loadon-startup>1</loadon-startup>。其中,数字越小代表优先级别越高。
       2、在Servlet容器启动后,客户首次向Servlet发送请求。
       3、当Servlet类文件被更新后,重新装载Servlet。


三、Servlet的运行过程
  1. 客户端通过HTTP提出请求。
  2. Web服务器接收该请求并将其发送给Servlet。如果这个Servlet尚未被加载,Web服务器将把它加载到Java虚拟机并执行它。
  3. Servlet程序将接收该HTTP请求并执行某种处理。
  4. Servlet会将处理后的结果向Web服务器返回应答。
  5. Web服务器将从Servlet收到的应答发回给客户端。

四、编写Servlet
1、Servlet接口实现类

      Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。

   HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
  HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。

2、编写servlet

       创建一个MyServlet继承HttpServlet,重写doGet和doPost方法,也就是看请求的方式是get还是post,然后用不同的处理方式来处理请求。

package com.om.Servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InputServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException { // 处理get请求
		String info = req.getParameter("info"); // 接收请求参数
		PrintWriter out = resp.getWriter(); // 准备输出
		out.println("<html>"); // 输出html元素
		out.println("<head><title>MLDNJAVA</title></head>"); // 输出html元素
		out.println("<body>"); // 输出html元素
		out.println("<h1>" + info + "</h1>"); // 输出html元素
		out.println("</body>"); // 输出html元素
		out.println("</html>"); // 输出html元素
		out.close(); // 关闭输出
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException { // 处理post请求
		this.doGet(req, resp); // 同一种方法体处理
	}
}

3、配置web.xml

在web.xml中配置InputServlet,让浏览器发出的请求知道到达哪个servlet,也就是让tomcat将封装好的request找到对应的servlet让其使用。

        <servlet>
		<!-- 给Servlet取名字,什么名字都可以,一般都会跟类名相同 -->
		<servlet-name>InputServlet</servlet-name>
		<!-- servlet的全路径类型。也就是servlet的位置 -->
		<servlet-class>com.om.Servlet.InputServlet</servlet-class>
	</servlet>
	<servlet-mapping>
	        <!-- 跟上面的servlet名字相同 -->
		<servlet-name>InputServlet</servlet-name>
		<!-- 浏览器通过这个url找到servlet。一定要有/开头,相当于项目名 -->
		 <url-pattern>/InputServlet</url-pattern>
	</servlet-mapping>
      在浏览器中输入地址,如何寻找到对应的servlet去执行,其过程如下:

  1. 首先浏览器通过http://localhost:8080/项目名/InputServlet来找到web.xml中的url-pattern。
  2. 匹配到了url-pattern后,就会在<servlet-mapping>中找到ervlet的名字InputServlet。
  3. 知道了名字,就可以通过servlet-name找到对应的<servlet>.
  4. 找到对应的<servlet>,也就能够知道servlet的位置<servlet-calss>,然后到其中找到对应的处理方式进行处理。

在实际开发过程中,开发工具都有向导可以指引我们直接创建servlet,并自动配置好web.xml,不需要手工进行配置。


(1)、Servlet访问URL映射配置

     由于客户端是通过URL地址访问web服务器中的资源,所以Servlet程序若想被外界访问,必须把servlet程序映射到一个URL地址上,这个工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。

  <servlet>元素用于注册Servlet,它包含有两个主要的子元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。
     一个<servlet-mapping>元素用于映射一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。如上面配置所示。
     同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。如下面这个例子,ServletDemo1被映射到了多个URL上:

<servlet>
      <servlet-name>ServletDemo1</servlet-name>
      <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class>
    </servlet>
  
    <servlet-mapping>
      <servlet-name>ServletDemo1</servlet-name>
      <url-pattern>/servlet/ServletDemo1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
      <servlet-name>ServletDemo1</servlet-name>
      <url-pattern>/1.htm</url-pattern>
    </servlet-mapping>
     <servlet-mapping>
      <servlet-name>ServletDemo1</servlet-name>
      <url-pattern>/2.jsp</url-pattern>
    </servlet-mapping>

       通过上面的配置,当我们想访问名称是ServletDemo1的Servlet,可以使用如下的几个地址去访问:
  http://localhost:8080/JavaWeb_Servlet_Study_20140531/servlet/ServletDemo1
  http://localhost:8080/JavaWeb_Servlet_Study_20140531/1.htm
  http://localhost:8080/JavaWeb_Servlet_Study_20140531/2.jsp

(2)、Servlet访问URL使用*通配符映射

      在Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式:一种格式是"*.扩展名",另一种格式是以正斜杠(/)开头并以"/*"结尾。如:

<servlet>
     <servlet-name>ServletDemo1</servlet-name>
     <servlet-class>gacl.servlet.study.ServletDemo1</servlet-class>
</servlet>
 
<servlet-mapping>
     <servlet-name>ServletDemo1</servlet-name>
     <url-pattern>/*</url-pattern>
</servlet-mapping>
*可以匹配任意的字符,所以此时可以用任意的URL去访问ServletDemo1这个Servlet.
如果一个请求URL,可以匹配上多个映射关系,则最终会匹配上最相近的servlet。
例如:Servlet1 映射到 /abc/* ;Servlet2 映射到 /* ;Servlet3 映射到 /abc ;Servlet4 映射到 *.do;
当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,Servlet引擎将调用Servlet1。
当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,Servlet引擎将调用Servlet3。
当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,Servlet引擎将调用Servlet1。
当请求URL为“/a.do”时,“/*”和“*.do”都匹配,Servlet引擎将调用Servlet2。
当请求URL为“/xxx/yyy/a.do”时,“/*”和“*.do”都匹配,Servlet引擎将调用Servlet2

五、Servlet的生命周期

       Servlet程序是运行在服务器端的一段Java程序,其生命周期将受到Web容器的控制。生命周期包括加载程序、初始化、服务、销毁、卸载5个部分。

    1、Servlet接口的某些对应方法.       

      各个生命周期,都可以在Servlet接口中发现对应的方法,这些方法如下:

public void init(ServletConfig config) throws ServletException  
public void service(ServletRequest req, ServletResponse res)throws ServletException, java.io.IOException  
public void destroy()  
public ServletConfig getServletConfig()  
public java.lang.String getServletInfo()  

      init():在Servlet实例化之后,Servlet容器会调用init()方法,来初始化该对象,主要是为了让Servlet对象在处理客户请求前可以完成一些初始化的工作,例如,建立数据库的连接,获取配置信息等。对于每一个Servlet实例,init()方法只能被调用一次。init()方法有一个类型为ServletConfig的参数,Servlet容器通过这个参数向Servlet传递配置信息。Servlet使用ServletConfig对象从Web应用程序的配置信息中获取以名-值对形式提供的初始化参数。另外,在Servlet中,还可以通过ServletConfig对象获取描述Servlet运行环境的ServletContext对象,使用该对象,Servlet可以和它的Servlet容器进行通信。

       service():容器调用service()方法来处理客户端的请求。要注意的是,在service()方法被容器调用之前,必须确保init()方法正确完成。容器会构造一个表示客户端请求信息的请求对象(类型为ServletRequest)和一个用于对客户端进行响应的响应对象(类型为ServletResponse)作为参数传递给service()方法。在service()方法中,Servlet对象通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。

      destroy():当容器检测到一个Servlet对象应该从服务中被移除的时候,容器会调用该对象的destroy()方法,以便让Servlet对象可以释放它所使用的资源,保存数据到持久存储设备中,例如,将内存中的数据保存到数据库中,关闭数据库的连接等。当需要释放内存或者容器关闭时,容器就会调用Servlet对象的destroy()方法。在Servlet容器调用destroy()方法前,如果还有其他的线程正在service()方法中执行,容器会等待这些线程执行完毕或等待服务器设定的超时值到达。一旦Servlet对象的destroy()方法被调用,容器不会再把其他的请求发送给该对象。如果需要该Servlet再次为客户端服务,容器将会重新产生一个Servlet对象来处理客户端的请求。在destroy()方法调用之后,容器会释放这个Servlet对象,在随后的时间内,该对象会被Java的垃圾收集器所回收。

      getServletConfig():该方法返回容器调用init()方法时传递给Servlet对象的ServletConfig对象,ServletConfig对象包含了Servlet的初始化参数。

      getServletInfo():返回一个String类型的字符串,其中包括了关于Servlet的信息,例如,作者、版本和版权。该方法返回的应该是纯文本字符串,而不是任何类型的标记(HTML、XML等)。

      2、整个生命周期过程。

      1、加载Servlet。
      Web容器负责加载Servlet,当Web容器启动时或者是在第一次使用这个Servlet时,容器会负责创建Servlet实例,但是用户必须通过部署描述符(web.xml)指定Servlet的位置(Servlet所在的包.类名称),成功加载后,Web容器会通过反射的方式对Servlet进行实例化。
       2、初始化
      当一个Servlet被实例化后,容器将调用init()方法初始化这个对象,初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库连接、读取资源文件信息等,如果初始化失败,则此Servlet将被直接卸载。
       3、处理服务
      当有请求提交时,Servlet将调用service()方法(常用的是doGet()或doPost())进行处理。在service()方法中,Servlet可以通过ServletRequest接收客户的请求,也可以利用ServletResponse设置响应信息。
       4、销毁
      当Web容器关闭或者检测到一个Servlet要从容器中被删除时,会自动调用destroy()方法,以便让该实例释放掉所占用的资源。当容器关闭或者一个Servlet长时间不使用时会自动进行销毁,而如果容器配置了动态加载(reloadable="true"),每当重新加载新的内容后,实际上Servlet也会销毁。
      5、卸载
     当一个Servlet调用完destroy()方法后,此实例将等待被垃圾收集器所回收,如果需要再次使用此Servlet时,会重新调用init()方法初始化。
    在正常情况下,Servlet只会初始化一次,而处理服务会调用多次,销毁也只会调用一次。但是如果一个Servlet长时间不使用的话,也会被容器自动销毁,而如果需要再次使用时会重新进行初始化的操作,即在特殊情况下初始化可能会进行多次,销毁也可能进行多次。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值