Inside Servlet 读书笔记 (3 )

   

第二部分  servlet介绍

4 使用servlet的原因

Servlet 技术的优势

 

1. 能够以进程运行

意思是说,与传统的服务器端组建相比(如cgi servlet是嵌入到服务器进程中的而不需要因为程序的调用而重新生成一个服务器程序的进程,这对服务器的负载有很大的好处。而且,由于统一进程服务器的信息可以和servlet共享。

2. 已编译

意思有两点

第一编译后的字节码文件相对原始的脚本程序执行效率有明显的提升

第二编译的过程就是一个出错的过程可以避免许多错误的产生。 同时也是她能够比原始的脚本开发更稳定,更容易修改。

第三代码显得比较紧凑,更安全

3. 防崩溃

由于servlet 运行在服务器端的JVM中,所以JVM可以控制程序而不会导致崩溃。

出现问题的时候JVM会把一个异常抛出到调用连接的顶端。

4. 跨平台

5. 跨服务器

6. 持久性

存储在内存中,已被调用,所以具备持久性

7. 可通过网络动态加载

8. 易于部署

9. 可扩展

10.             多线程

11.             面向对象

12.             独立于协议

13.             安全

14.             java编写

可以完全的应用java api中的既有功能。

 

 

新技术 fast cgi  

改进了cgi的每个请求要生成一个新的进程的做法

每个cgi程序需要一个新的进程 这样,在性能上还是低于 只需一个进程的servlet

 

5 servlet 基础

Servlet 的基本结构

所有的servlet都扩展了GenericServlet HttpServlet 这两个类。

1GenericServlet 顾名思义就是一般servlet。而HttpServlet是单独用来处理http协议的servlet 基础类。这些类提供了一个框架。用于创建一个servlet 它有着强大的默认功能。

2)所有的servlet至少要覆盖一种方法,在其中实现自己特定的功能。Service方法是默认的方法。它用于响应客户请求并被服务器自动调用的方法。(在编写HttpServlet时我们编写的servlet类中可以不覆盖这个方法。这时默认的service方法会自动被调用,并(根据hppt请求的方法)调用另外一个方法来响应请求。|相应的在其他servlet中我们可以覆盖这个service方法来实现我们自己的功能。)

除了service 方法外servlet 还有两个多数要知性的方法:init() destroy()

他们分别是servlet初始化和卸载所对应的方法。

                                                   

以上三个方法都是GenricServlet HttpServlet类默认执行的方法。所以,在没有特殊要求的情况下,我们编写的servlet中可以不作明确的定义。


public MyServlet extends GenricServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

  

}
 

public MyServlet extends HttpServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

}
 

  

Servlet 的生命周期

public MyServlet extends GenricServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

  

}
 

public MyServlet extends HttpServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

}
 

  

Servlet 的生命周期

public MyServlet extends GenricServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

  

}
 

public MyServlet extends HttpServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

}
 

  

Servlet 的生命周期

public MyServlet extends GenricServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

  

}
 

public MyServlet extends HttpServlet 



pubic 
void init() 



//init code 

}
 

pubic 
void doPost() 



//init code 

}
 

pubic 
void doGet() 



//init code 

}
 

}
 

  

Servlet 的生命周期

                                                   

(1) 服务器启动时,当servlet被客户端首次请求或被配置好。(?????不明白,乱七八糟的)这时服务器加载servlet代码。servlet 加载可以由一个java类加载工具从本地或远程地址来实现实现。

这一步骤等同于以下代码:

//加载地址+名称为classNameservlet类。

Class c=Class.forName(“className”);

 ClassforName方法就是用来加载地址为上例className的。

2)服务器实例化一个servlet类实例。这个实例可以借助多线程的特性服务于许多不同的请求。但是,这样对安全性是一大隐患。为构建线程安全的servlet 我们编写的servlet代码必须实现SingleThreadModel接口。 而实现了这一接口的程序是不能支持多线程的。这样,服务器会为实例构建一个实例池,并从中取出一个服务于心请求的servlet实例。用于实现不同请求的响应。

这一步骤相当于:

//构建 c 的实例

Servlet s=(Servlet)c.newInstance();

3)服务器调用servletinit()这个方法的目的是给每个实例初始化。

同时也是在首次请求以前(请求调用实例以前),实例初始化结束的标志。

 

4 客户发出对某一servlet的请求(实际上是对某一业务逻辑的请求)。服务器把客

户端的请求信息接收.并利用这些信息构分别造出一个

ServletRequest/HttpServletRequest

和一个

ServletResponse/HttpServletResponse

  

5 服务器调用servletservice()方法 (对于HttpServlet service将调用更为细节的方法doGetdoPost)当并行请求到来时多个service方法可以同时运行在单独的线程中。(除非servlet实现SingleThreadModel接口)

 

6)通过分析ServletRequestHttpServletRquequest 对象service方法处理客户的请求,并用ServletResponse HttpServletResponse 来响应请求。

 

7 如果服务器收到另一个对servlet的请求这个过程回到(5)继续执行。

 

8)一旦容器检测到一个servlet需要卸载 这个肯呢个是因为资源的回收或是因为这个在被关闭。服务器会在所有的servlet service 线程完成之后或是超时之后调用servletdestroy方法然后就可以进行无用存储单元的清理。

 

服务器加载servlet

服务器创建servlet的实例

服务器调用servletinit方法

Servlet(其实应该是servlet的实例)等待直到受到一个请求或被服务器卸载

服务器调用servletservice方法

收到请求

Servletservive方法处理请求并返回输出到客户端

服务器调用servletdestroy方法后卸载servlet

卸载servlet

 

注意:关于init方法的执行时间参见init方法的执行时间上遇到的问题的解决
Servlet 实例

 

实例 1 通用servlet

 

package ysong;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class TimeServlet extends GenericServlet
{
public void service(ServletRequest rq,ServletResponse rsp)throws ServletException,java.io.IOException
{
java.io.PrintWriter 
out=rsp.getWriter();                    
out.println(new java.util.Date());
}

}

 

 

   

实例2 HTTP Servlet


package ysong;

import javax.servlet.
*;
import javax.servlet.http.
*;
import java.io.
*;
import java.util.
*;

public class SampleHttpServlet
    extends HttpServlet 
{
  
int numRequests = 0;
  String lastRequest 
= (new Date()).toString();
  Properties prop 
= null;

  
public void init() throws ServletException {
    prop 
= new Properties();

    
try {
      File file 
= new File("SampleServlet.properties");

      
if (file.exists()) {
        FileInputStream fileIn 
= new FileInputStream(file);
        prop.load(fileIn);
        numRequests
= Integer.parseInt(prop.getProperty("RequestCount""0"));
        lastRequest
=prop.getProperty("LastRequest",(newDate()).toString());
      }

      
else {
      }


    }

    
catch (Exception e) {
    }


  }


  
public void service(HttpServletRequest request,
                      HttpServletResponse response
                      ) throws ServletException, IOException 
{
    response.setContentType(
"text/html");
    PrintWriter 
out = response.getWriter();
    
out.println("<html>");
    
out.println("<head><title>sampleServlet</title></head>");
    
out.println("<body>");
    
out.println("<h1>Hello World</h1>");
    
out.println("This servlet has been request " + this.numRequests + " times ");
    
out.println("Last Request at " + this.lastRequest);
    
out.println("</body></html>");
    lastRequest
=(new Date()).toString();
    
out.close();
  }

  
public String getServletInfo()
  
{
    
return "author : ysong version : 1.0";
  }

  
  
public void destroy() 
  
{
    File file
=new File("SampleServlet.properties");
    
try {
      FileOutputStream fileOut 
= new FileOutputStream(file);
      
      prop.put(
"RequestCount",Integer.toString(numRequests));
      prop.put(
"LastRequest",lastRequest);      
      prop.store(fileOut,
"SampleServlet.properties");
    }

    
catch (Exception e) {
    }

    
  }


}

 

init()中判断SampleServlet.properties是否存在。

 

service中为servlet的计数添加数值。(此部为servlet调用的必经之路)

 

这个例子在服务器shutdown的时候才会执行destroy。如果没有SampleServlet.properties 则会在服务器shutdown的时候生成,而生成的代码是写在destroy方法中的。    

posted @ 2004-11-20 16:12  黄金¤小草  阅读(276)  评论(0)    收藏  举报