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
闽公网安备 35060202000074号