Java Servlet 编程及应用之六

作者:网络 来源:佚名 更新时间:2008-11-17 15:22:30 点击:
国内最大的酷站演示中心!

  servlet 链提供了servlet 应用的一种特殊功能。与unix 和dos 命令中的管道类似,可以将多个servlet 以特定顺序链接起来。在servlet 链中,一个servlet 的输出被当作下一个servlet 的输入,而链中最后一个servlet 的输出被返回到浏览器。

  编程思路:首先编写一个表过滤器servlet,它的作用主要是按照一定的表格格式输出,在通过servlet 表过滤器(tablefilter.java)后,无格式化的servlet(ghq.java)所有的行将会被格式化成html表格。

  表过滤器 tablefilter.java 的源代码如下:(代码节选)

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class tablefilter extends httpservlet
{
 public void service(httpservletrequest req, httpservletresponse resp)
 throws servletexception, java.io.ioexception
 {
  // get all headers set by the previous servlet and echo them
  java.util.enumeration e = req.getheadernames();
  while (e.hasmoreelements()) {
   string header = (string)e.nextelement();
   string value = req.getheader(header);
   resp.setheader(header, value);
  }
  // get the input and output streams
  servletinputstream in = req.getinputstream();
  servletoutputstream out = resp.getoutputstream();
  // only process if this is a recognized mime type
  string type = req.getcontenttype();
  if (type.equals("text/html") || type.equals("text/table") ||
type.equals("application/x-www-form-urlencoded")) {
   resp.setcontenttype("text/html");
   // create a buffered reader that we can use to read
   // a single line at a time
   bufferedreader br = new bufferedreader(new inputstreamreader(in));
   boolean intable = false;
   int tablecols = 0;
   boolean headerrow = false;
   // read until no more data exists
   while (true) {
    string s = br.readline();
    // null indicates end of file
    if (s == null) {
     break;
    }
   // if we are in the middle of a table command, process
   // the line
   if (intable) {
    // search for the end of the table
    if (s.startswith("<!--end table")) {
     out.println("</table></center>");
     intable = false;
    }
    else {
     // we've got a row of a table - format it
     s = formatrow(s, tablecols, headerrow);
     headerrow = false;
    }
   }
   else {
 
    // search for the start of a table
    if (s.startswith("<!--table")) {
     int pos = s.indexof("columns=");
     tablecols = 0;
     if (pos >= 0) {
      // get the number of columns
      string cols = s.substring(pos + 8);
      int endpos = cols.indexof(" ");
      if (endpos > 0) {
       cols = cols.substring(0, endpos);
      }
     tablecols = integer.parseint(cols);
    }
   .........
   .........

  这个表过滤器servlet 分析另一个servlet 的输出,查找含有特殊格式指令的html 注释,这些指令包括表有多少列、是否显示表头等等。在该表格格式指令之后的所有行将会被格式化成一个html 表格。这样链中的前一个servlet 只要简单地将数据用逗号分隔,数据就可以一行一行地直接输出了,而无须修改这些数据格式化html 表格。

||| 国内最大的酷站演示中心!

  没有格式化输出的html 表格ghq.java 的源代码如下:

import javax.servlet.*;
import javax.servlet.http.*;
public class ghq extends httpservlet
{
 public void doget(httpservletrequest req, httpservletresponse resp)
 throws servletexception, java.io.ioexception
 {
  // create a printwriter to write the response
  java.io.printwriter out = new java.io.printwriter(resp.getoutputstream());
  // set the content type of the response
  resp.setcontenttype("text/html;charset=gb2312");
  // print the html header
  out.println("<html>");
  out.println("<head>");
  out.println("<title>java servlets sample - " + "通讯录 </title>");
  out.println("</head>");
  out.println("<h2><center>");
  out.println("通讯录</center></h2>");
  out.println("<br>");
  // output special table formatting instructions for
  // the tablefilter servlet
  out.println("<!--table columns=3 header=yes-->");
  // output the table
  out.println("姓名,性别,联系电话");
  out.println("谷物,男,4324552");
  out.println("江淮,女,2345265");
  out.println("王冠,男,7867655");
  out.println("张罗,男,5654343");
  out.println("许愿,女,8876554");
  out.println("<!--end table-->");
  // wrap up
  out.println("</html>");
  out.flush();
  out.close();
 }
 public void init(servletconfig cfg)
 throws servletexception
 {
  super.init(cfg);
 }
 public void destroy()
 {
  super.destroy();
 }
}

  编程技巧说明:

  触发servlet 链,有3种触发servlet 链的方式:

  * 通过在url 中用逗号分隔的多个servlet 来直接触发。

  * 将多个servlet 指定同一个别名,然后通过别名方式来触发servlet 链。

  * 指定一种mime 类型,规定凡是这种mime 类型的响应都要通过某一个servlet 来过滤,这也是一种servlet 链的应用。

  其中第三种应用比较特殊,可以用来格式化文本,在一些internet 翻译网站也可能用来对结果文本进行翻译。

  用第一种直接在url中触发servlet 链的方法很简单,只要在url后面将链中的servlet 用逗号按顺序隔开即可。在浏览器的地址栏输入url 如下:

  http://192.168.10.1/servlet/ghq,tablefilter

  用第二种方法使用别名方式指定servlet 链,如采用jrun servlet 引擎,则在jrun 的servlet url mapping 功能中进行配置。如在"virtual path/extension" 项中输入 " /test ",在"servlet invoked" 项中输入" ghq,tablefilter ",则在用别名触发servlet 的url 如下:

  http://192.168.10.1/test