Servlet详解

1.什么是servlet?

    Servlet(Server Applet),全称Java Servlet,未有中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。

Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

最早支持Servlet标准的是JavaSoft的Java Web Server。此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。

   我们可以把Servlet看成可以看成是用java编写的CGI.

   CGI(Common GatewayInterface)是HTTP服务器与你的或其它机器 上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。

2.Servlet 特点

        1.可移植性

       Servlet用Java编写,ServletAPI具有完善的标准。

       2.功能比较强大

          可以使用Java API的所有功能

       3.高效耐久

         一旦载入,它就驻留在内存中,加快响应速度

       4.方便

          Servlet提供了大量的实用工具例程,例如自动地解析和解码HTML表单数据、读取和设置HTTP头、处理Cookie、跟踪会话状态等。

3.工作模式

          客户端发送请求至服务器

          服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器

          服务器将响应返回客户端


4.Servlet继承关系

Servlet接口中定义了五个方法:

Methods
public void destroy()
由 servlet 容器调用,指示将从服务中取出该 servlet。此方法仅在 servlet 的 service 方法已退出或者在过了超时期之后调用一次。在调用此方法之后,servlet 容器不会再对此 servlet 调用service 方法。

此方法为 servlet 提供了一个清除持有的所有资源(比如内存、文件句柄和线程)的机会,并确保任何持久状态都与内存中该 servlet 的当前状态保持同步。

public void

init(ServletConfig config) throwsServletException
由 servlet 容器调用,指示将该 servlet 放入服务。

servlet 容器仅在实例化 servlet 之后调用 init 方法一次。在 servlet 可以接收任何请求之前,init 方法必须成功完成。servlet 容器无法将 servlet 放入服务,如果init 方法:

public void service(ServletRequest req, ServletResponse res) throws ServletException, java.io.IOException
由 servlet 容器调用,以允许 servlet 响应某个请求。

此方法仅在 servlet 的 init() 方法成功完成之后调用。

应该为抛出或发送错误的 servlet 设置响应的状态代码。

servlet 通常运行在可同时处理多个请求的多线程 servlet 容器中。开发人员必须知道要同步对所有共享资源(比如文件、网络连接以及 servlet 的类和实例变量)的访问。有关 Java 中多线程编程的更多信息,可从the Java tutorial on multi-threaded programming 中获得。

 

Properties
public ServletConfig getServletConfig()
返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init 方法的对象。

此接口的实现负责存储 ServletConfig 对象,以便此方法可以返回该对象。实现此接口的 GenericServlet 类已经这样做了。

public String getServletInfo()
返回有关 servlet 的信息,比如作者、版本和版权。

此方法返回的字符串应该是纯文本,不应该是任何种类的标记(比如 HTML、XML,等等)。

      在web容器启动后,会读取标注(Annotation)或者web.xml的配置,根据当中的每个Servlet配置,将servlet类载入,并实例化,并为每个servlet的配置产生一个ServletConfig对象,然后调用Servlet里面的init()方法,并将产生的ServletConfig对象当作参数输入进去。

    ServletConfig对象:
       ServletConfig是针对特定的Servlet的参数或属性。ServletConfig是表示单独的Servlet的配置和参数,只是适用于特定的Servlet。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对本servlet有效,一个servlet的ServletConfig对象不能被另一个servlet访问。

1.首先要设置初始化参数,如果只有一个特定的servlet要设定的参数(Servlet名字以及其它参数等),其它servlet不能共享,应该配置为ServletConfig参数,如一个读取附件的servlet要用到绝对目录,而别的servlet不会用到:

<web-app>
<servlet>
     <servlet-name>GetAtt</servlet-name>
     <servlet-class>mail.GetAttServlet</servlet-class>
   <init-param>
    <param-name>absPath</param-name>
    <param-value>/usr/mail/ax/axman/Maildir/</param-value>
 </init-param>
</servlet>
</web-app>

2.其次要取得ServletConfig对象:

1).从init()方法中得到.

public class Test extends HttpServlet {
   ServletConfig config;
    public void init(ServletConfig config) throws ServletException {
    super.init(config);
    this.config = config;
}
2).从getServletConfig()方法中得到.

ServletConfig config=this.getServletConfig();

if(config.getInitParameter("absPath").eaquals("adsd"){
.......
}

    GenericServlet类

     GenericServlet 类可以说时JDK中最重要的类,也是最基本的类。程序员要编写Servlet 应用程序,一般要继承JSDK 提供的GenericServlet 类或它的子类HttpServlet类。service() 方法是类GenericServlet中最重要的方法。每次客户向服务器发出请求时,服务器就会调用这个方法。编程人员若想对客户的请求进行响应的话,就必须覆盖这个方法,并在这个方法中加入自己的代码来具体实现对客户的响应。Service有两个参数,ServletRequest 和ServletResponse。其中ServletRequest 保存了客户向服务器发请求的各种属性。

对象ServletResponse用来设置如何对客户进行响应,它有以下三个方法:

      *setContentType(String) 用来设置对客户响应的类型。

      *setContentlength(int) 用来设置对客户响应的长度。

      *getOutputStream() 它返回一个写响应数据的输出流。

例如:

public class HelloWorldServlet extends GenericServlet {

	@Override
	public void service(ServletRequest req, ServletResponse res)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		Date today = new Date();
		ServletOutputStream out = res.getOutputStream();
		out.println("HELLO WORLD");
		out.println(today.toString());
		
	}
	
}


 GenericServlet用于定义一般的且与协议无关的servlet 如果是继承GenericServlet的话,必须要重写service方法service方法是一个抽象方法,并且在每次访问servlet都会访问

在访问继承了HttpServlet的servlet的时候,首先访问的还是service方法 获取请求的类型,根据类型判断调用具体的doXXX()方法,所以通常继承HttpServlet抽象类的servlet只需要重写doXXX()方法

 继承genericServlet和继承HttpServlet的差别:
 1、继承genericServlet必须要重写service方法,而HttpServlet不需要
  2、genericServlet通常用于处理与请求协议无关的servlet,httpServlet处理与HTTP协议相关的请求
  3、继承httpServlet的话,最少必须要重写doXXX()方法之一
HttpServlet中Service方法源代码如下:

 protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);        
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }
通过源码我们可以看出,在Service方法中,系统已经帮我们处理好了get和post方式请求,所以我们在使用Servlet的时候,直接继承于HttpServlet,不需要重写Service方法,只需要重写dopost或者doget方法。

 

你可能感兴趣的:(Servlet详解)