自定义标记2

 
基本标记说明
       在上一节中我们已经做了一个自定义的标记,制作标记的基本方法和在tomcat的部署已经基本了解,这一节我们要了解自定义标机的详细信息。
1、  基本标记:标记处理程序类
没有体或者仅包含体的标记应该扩充TagSupport类。这是一个内建的类,在javax.servlet.jsp.tagext包中,上一节已作了详细的说明,它实现Tag交口并包含有所需的大量的标准功能的基本标记。由于你将使用其他类,因此,你的标记通常也应该导入javax.servlet.jsp和java.io包中的类。大多数标记的实现都在包声明之后包含以下import语句:
              i mport javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

import java.io.*;
       对于没有属性或体的标记,需要做的是从在doStartTag方法,该方法定义了在请求时调用的并且其调用位置在该元素的开始标记出的代码。为了生成输出,该方法应该借助getOut从自动定义的pageContext字段中获得JspWriter(通过使用与定义out变量的用于jsp业的特定Writer)。除了getOut方法外,pageContext字段(类型为PageContext)还拥有获得与该请求相关的其他数据结构的方法,其中最重要的方法是getRequest,getResponse,getServletContext和getSession。
       由于JspWriter的print方法抛出IOException异常,因此该print语句应该在try/catch块内。为了向用户报告其他类型的错误,可以声明doStartTag方法抛出一个JspException异常,然后再错误出现时抛出它。
       如果你的标记没有标记体,则doStartTag应该返回SKIP_BODY常量,该常量知识系统忽略在该标记的开始和技术标记之间的任何内容。正如我们不久将看到的,SKIP_BODY有时甚至在有标记体(例如,你有时包含它而有时又忽略它)是也是有用的,但是,我们在此开发的这个简单标记将作为一个独立标记使用(<prefix:tagname />),因此没有体部分。
       程序清单2-1给出一个标记的实现,搞标记使用此方法通过primes类的使用程序清单2-2产生随机的50位的素数。
程序清单 2-1        SimplePrime.java
package moreservlets.tags;
 
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import java.math.*;
import moreservlets.*;
 
/**Generates a prim of approximately 50 digits.
  * (50 is actually the length of the random number
  * generated -- the first prime above that number will
  * be returned.)
  * @study by bai
  */
public class SimplePrimeTag extends TagSupport
{
    protected int len =50;
   
    public int doStartTag()
    {
       try
       {
           JspWriter out= pageContext .getOut();
           BigInteger prime=Primes.nextPrime(Primes.random( len ));
           out.print(prime);
       } catch (IOException ioe)
       {

           System.out.println("Error generating prime: "+ioe);

       }
       return ( SKIP_BODY );
    }
}
程序清单2-2        Primes.java
package moreservlets;
 
import java.math.BigInteger;
 

/*A few utilities to generate a large random BigInteger,

 * and find the next prime number above a given BigInteger.

 */
public class Primes
{
    private static final BigInteger ZERO =BigInteger. ZERO ;
    private static final BigInteger ONE =BigInteger. ONE ;
    private static final BigInteger TWO = new BigInteger( "2" );
   
    private static final int ERR_VAL =100;
   
    public static BigInteger nextPrime(BigInteger start)
    {
       if (isEven(start))
           start=start.add( ONE );
       else
           start=start.add( TWO );
       if (start.isProbablePrime( ERR_VAL ))
           return (start);
       else
           return (nextPrime(start));
    }
    private static boolean isEven(BigInteger n)
    {
       return (n.mod( TWO ).equals( ZERO ));
    }
    private static StringBuffer[] digits =
    {
       new StringBuffer( "0" ), new StringBuffer( "1" ),
       new StringBuffer( "2" ), new StringBuffer( "3" ),
       new StringBuffer( "4" ), new StringBuffer( "5" ),
       new StringBuffer( "6" ), new StringBuffer( "7" ),
       new StringBuffer( "8" ), new StringBuffer( "9" ),
    };
    private static StringBuffer randomDigit( boolean isZeroOK)
    {
       int index;
       if (isZeroOK)
       {
           index=( int )Math.floor(Math.random()*10);
       }
       else
       {
           index=1+( int )Math.floor(Math.random()*9);
       }
       return ( digits [index]);
    }
    /**Create a random big integer where every digit is
      * selected randomly (except that the first digit
      * cannot be a zero).
      */
    public static BigInteger random( int numDigits)
    {
       StringBuffer s= new StringBuffer( "" );
       for ( int i=0;i<numDigits;i++)
       {
           if (i==0)
           {
//            First digit must be non-zero.
              s.append(randomDigit( false ));
           }
           else
           {
              s.append(randomDigit( true ));
           }         
       }
       return ( new BigInteger(s.toString()));
    }
    /**Simple command - line program to test.Enter number
      * of digits,and it picks a random numbers
      * above that.
      */
    public static void main(String[] args)
    {
       int numDigits;
       try
       {
           numDigits=Integer.parseInt(args[0]);
       } catch (Exception e)
       {

           //No args or illegal arg.

           numDigits=150;
       }
       BigInteger start=random(numDigits);
       for ( int i=0;i<50;i++)
       {
           start=nextPrime(start);

           System.out.println("Prime "+i+" = "+start);

       }
    }
}
 
2、 基本标记:标记库描述符文件
描述符文件的一般格式几乎总是相同的:它应该包含一个 xml版本的标识符,后跟一个 DOCTYPE声明,在跟一个 taglib容器元素,如程序清单 1-2所示。需要了解的重要部分是进入 taglib元素中的内容:即 tag元素。对于没有属性的标记, tag元素应该在 <tag></tag>之间包括四个元素:
1name 它的体定义 taglib指令的前缀将附在其上的基本标记名。在这里,我们使用: <name> simplePrime    <name>     定义基本标记名为 simplePrime
2tag-class      它给出标记处理程序的全限定类名。在侧,我们使用:
<tag-class>moreservlets.tags.SimplePrimeTag</tag-class>
    3 body-content   可以省略,但是,对于没有体的标记,如果给出此元素,则其值应该为 empty 。带有标准托的标记被认为是标准 jsp ,使用值 JSP (缺省值),只有很少标记的处理程序本身完全使用值 tagdependent 处理标记体。对于这里讨论的 SimplePrimeTag ,我们使用 empty 值: <body-content>empty</body-content>

    4description    它提供一个短描述。在此我们使用了:<description> Generates primes </description>

 
程序清单 2-3       mspjsp-taglib.tld

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE taglib

        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"

    "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">
 
<taglib>
 
 <tlib-version>1.0</tlib-version>
 <jsp-version>1.2</jsp-version>
 <short-name>msajsp-tags</short-name>
 <description>

    A simple tab for the examples

 </description>
 
 <tag>

    <name>example</name>

    <tag-class>moreservlets.tags.ExampleTag</tag-class>

    <body-content>empty</body-content>

    <description> Output some strings </description>   

 </tag>  
 
 <tag>

    <name>simplePrime</name>

    <tag-class>moreservlets.tags.SimplePrimeTag</tag-class>

    <body-content>empty</body-content>

    <description> Generates primes </description>   

 </tag> 

     

 </taglib>
3、 基本标记: jsp 文件
使用定制的标记的 jsp文档需要使用 taglib指令,提供一个给出标记库描述符文件位置的 uri属性和一个指定将附加到主标记名(连同一个逗号)上的短串的 prefix属性。请记住, uri属性可以是绝对 URL或相对的 URL。当初此学习时,再容易的方法是以用一个简单的相对 URL对应一个 TLD文件,该 TLD文件与使用它的 jsp也在同一个目录中。但是,当我们深入到 web应用时,将看到对于大的应用来说,将 TLD文件放在 WEB-INF目录的子目录中更有意义,这样的配置更宜于在多个目录的 jsp业中冲用同一个 tld文件,并且防止最终用户检索 tld文件,本文是利用第二种方法。
程序清单 3-4       SimplePrimeExample.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

 
<html>

    <head>

    <%@ taglib uri="msajsp-taglib.tld" prefix="msajsp" %>

    <title>Some 50-Digit Prime</title>   

    <body>

    <H1>Some 50-Digit Prime</H1>

    <UL>

    <LI><msajsp:simplePrime />
    <LI><msajsp:simplePrime />
    <LI><msajsp:simplePrime />
    <LI><msajsp:simplePrime />

    </UL>

    </body>

</html>
    按照在第一节中将的部署方法部署文件,在浏览器中输入 :
localhost:8080/simpletag/SimplePrimeExample.jsp
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值