·配置 Tomcat5.5 站点

n 创建应用程序 viewhelper

·实现定制标签 Helper 的策略

下面我们创建一个自定义的标签 Tag，完成格式化日期和货币的功能。

n 创建 public class FormatTag extends BodyTagSupport，自定义标签类，完整代码如下：

package jsplession;

import javax.servlet.jsp.*;

import javax.servlet.jsp.tagext.*;

import java.io.*;

import java.util.*;

import java.text.*;

public class FormatTag extends BodyTagSupport {

/* Locale object for internationalization of content */

private Locale locale;

/* Tag Attributes */

protected int format;

/* Static Constants */

public final static int DATE_LONG = 0;

public final static int NUMERIC_DECIMAL = 1;

public final static int NUMERIC_ROUNDED = 2;

public final static int NUMERIC_CURRENCY = 3;

public FormatTag() {

locale = Locale.getDefault();

}

public void setLocale(Locale locale) {

this.locale = locale;

}

/* Process Tag Body */

public int doAfterBody() throws JspTagException {

try {

BodyContent body = getBodyContent();

JspWriter out = body.getEnclosingWriter();

/* Get Input Value */

String textValue = body.getString().trim();

/* Output Formatted Value */

out.println(formatValue(textValue));

} catch (IOException e) {

throw new JspTagException(e.toString());

}

return SKIP_BODY;

}

/* Process End Tag */

public int doEndTag() throws JspTagException {

return EVAL_PAGE;

}

private String formatValue(String _input) {

String formattedValue = "";

try {

switch (format) {

case DATE_LONG: {

Calendar cal = Calendar.getInstance();

cal.setTime(DateFormat.getDateInstance(DateFormat.SHORT).parse(

_input));

SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d, yyyy");

formattedValue = df.format(cal.getTime());

break;

}

case NUMERIC_DECIMAL: {

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getInstance(locale);

dcf.setMinimumFractionDigits(2);

dcf.setMaximumFractionDigits(2);

formattedValue = dcf.format(dcf.parse(_input));

break;

}

case NUMERIC_ROUNDED: {

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getInstance(locale);

dcf.setMinimumFractionDigits(0);

dcf.setMaximumFractionDigits(0);

formattedValue = dcf.format(dcf.parse(_input));

break;

}

case NUMERIC_CURRENCY: {

float f = Float.parseFloat(_input);

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getCurrencyInstance();

formattedValue = dcf.format(f);

break;

}

}

} catch (Exception e) {

System.out.println(e.toString());

}

return formattedValue;

}

/* Attribute Accessor Methods */

public int getFormat() {

return this.format;

}

public void setFormat(int _format) {

this.format = _format;

}

}

1. 定义 private Locale locale，我们用这个变量来按照地区格式化货币。同时定义 setter 方法。

2. 定义四个静态常量，代表格式化日期或数字的类型：

·public final static int DATE_LONG = 0，表示长日期格式

·public final static int NUMERIC_DECIMAL = 1，表示十进制数字

·public final static int NUMERIC_ROUNDED = 2，表示整型数字

·public final static int NUMERIC_CURRENCY = 3，表示货币

3. 定义 protected int format，标签的属性（Attribute）指定格式化的类型。在使用标签时要提供的参数，取值是上面四个常量之一。同时定义 setter 和 getter 方法

4. 定义构造方法 public FormatTag()，获得默认的地区属性，即 locale = Locale.getDefault()

5. 定义 private String formatValue(String _input)，按照 format 指定的类型格式化 String _input。使用 switch (format)语句，分别格式化：

· case DATE_LONG，格式化成长日期，代码如下：

Calendar cal = Calendar.getInstance();

cal.setTime(DateFormat.getDateInstance(DateFormat.SHORT).parse(

_input));

SimpleDateFormat df = new SimpleDateFormat("EEE, MMM d, yyyy");

formattedValue = df.format(cal.getTime());

· case NUMERIC_DECIMAL，格式化成十进制数字，代码如下：

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getInstance(locale);

dcf.setMinimumFractionDigits(2);

dcf.setMaximumFractionDigits(2);

formattedValue = dcf.format(dcf.parse(_input));

· case NUMERIC_ROUNDED，格式化成整型数字，代码如下：

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getInstance(locale);

dcf.setMinimumFractionDigits(0);

dcf.setMaximumFractionDigits(0);

formattedValue = dcf.format(dcf.parse(_input));

· case NUMERIC_CURRENCY，格式化成货币，代码如下：

float f = Float.parseFloat(_input);

DecimalFormat dcf = (DecimalFormat) NumberFormat

.getCurrencyInstance();

formattedValue = dcf.format(f);

6. 重写 public int doAfterBody()，输出格式化后的数据：

· 获得标签中的 body，即 BodyContent body = getBodyContent();String textValue = body.getString().trim()

· 输出格式化后的数据，即 JspWriter out = body.getEnclosingWriter(); out.println(formatValue(textValue))

· return SKIP_BODY 跳过了开始和结束标签之间的代码，使标签处理继续下去。

7. 重写 public int doEndTag()，return EVAL_PAGE 即继续执行标签下面的内容。

n 创建 TLD 文件：WEB-INF/tlds/helpers.tld，在文件中描述和声明我们自定义的标签类。完整代码如下：

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

version="2.0">

<tlib-version>1.0</tlib-version>

<short-name>helperTags</short-name>

<uri>helpers</uri>

<description>

Tag library to support the View-Helper examples

</description>

<tag>

<name>FormatTag</name>

<tag-class>jsplession.FormatTag</tag-class>

<body-content>JSP</body-content>

<attribute>

<name>format</name>

<required>yes</required>

<rtexprvalue>true</rtexprvalue>

</attribute>

</tag>

</taglib>

n 在 web.xml 文件中声明自定义的标签，完整代码如下：

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>viewhelper</display-name>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

<jsp-config>

<taglib>

<taglib-uri>/helpers</taglib-uri>

<taglib-location>/WEB-INF/tlds/helpers.tld</taglib-location>

</taglib>

</jsp-config>

</web-app>

n 创建 public class FormattingModel，充当模型的角色，持有日期和/或者货币数据。FormattingModel 包含二个私有变量 private String dateValue 和 private String currencyValue，分别用于持有日期和货币数据。完整代码如下：

package jsplession;

import java.io.*;

public class FormattingModel implements Serializable {

private String dateValue;

private String currencyValue;

public FormattingModel() {

}

/* Accessor Methods */

public void setDateValue(String _date) {

this.dateValue = _date;

}

public String getDateValue() {

return this.dateValue;

}

public void setCurrencyValue(String _currency) {

this.currencyValue = _currency;

}

public String getCurrencyValue() {

return this.currencyValue;

}

}

n 创建 FormatHelper.jsp，我们用这个 Jsp 文件中测试自定义的标签，完整代码如下：

<%@ page language="java" contentType="text/html; charset=gbk"

pageEncoding="gbk"%>

<!-- Declare tag that we'll use as our helper -->

<%@ taglib uri="/helpers" prefix="helpers" %>

<html>

<head>

<title>Text Formatting Example</title>

</head>

<body>

<basefont face="宋体">

<!-- Declare bean that will act as our model -->

<jsp:useBean id="myBean" class="jsplession.FormattingModel"/>

<jsp:setProperty name="myBean" property="dateValue" value="07-03-01"/>

<jsp:setProperty name="myBean" property="currencyValue" value="23500.253"/>

<!-- Display Formatted Values (using helper) -->

<center>

<h1>各种日期和货币的格式</h1>

<br><br>

<table cellpadding="5">

<tr>

<th>格式</th>

<th>原始值</th>

<th>格式化后的值</th>

</tr>

<tr>

<td>长日期</td>

<td>

<jsp:getProperty name="myBean" property="dateValue"/>

</td>

<td>

<helpers:FormatTag format="<%= jsplession.FormatTag.DATE_LONG %>">

<jsp:getProperty name="myBean" property="dateValue"/>

</helpers:FormatTag>

</td>

</tr>

<tr>

<td>十进制 (NN.NN)</td>

<td><%= myBean.getCurrencyValue() %></td>

<td>

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_DECIMAL %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

</td>

</tr>

<tr>

<td>整型 (N,NNN)</td>

<td><%= myBean.getCurrencyValue() %></td>

<td>

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_ROUNDED %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

</td>

</tr>

<tr>

<td>货币 ($N,NNN.NN)</td>

<td><%= myBean.getCurrencyValue() %></td>

<td>

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_CURRENCY %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

</td>

</tr>

</table>

</center>

</body>

</html>

其中：

· <%@ taglib uri="/helpers" prefix="helpers" %>，声明我们要用到的自定义标签库 helpers

· <jsp:useBean id="myBean" class="jsplession.FormattingModel"/>创建一个模型来存储日期和数字数据

· <jsp:setProperty name="myBean" property="dateValue" value="07-03-01"/>，设置日期数据

· <jsp:setProperty name="myBean" property="currencyValue" value="23500.253"/>，设置货币数据

· 下面的代码使用自定义标签输出日期数据

<helpers:FormatTag format="<%= jsplession.FormatTag.DATE_LONG %>">

<jsp:getProperty name="myBean" property="dateValue"/>

</helpers:FormatTag>

· 类似的，用自定义标签输出三种格式的数字数据：

(1) 十进制格式：

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_DECIMAL %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

(2) 整型格式：

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_ROUNDED %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

(3) 货币格式：

<helpers:FormatTag format="<%= jsplession.FormatTag.NUMERIC_CURRENCY %>">

<%= myBean.getCurrencyValue() %>

</helpers:FormatTag>

·部署运行

n 部署文件

· 编译 FormatTag.java 和 FormattingModel.java，把 class 文件放到 WEB-INF\classes\jsplession 目录下。

· 把 FormatHelper.jsp 放到应用程序 viewhelper 目录下。

· TLD 文件 helpers.tld 放到 WEB-INF\tlds 目录下。

n 启动 Tomcat

n 在 IE 浏览器的地址栏中输入 http://localhost:8080/viewhelper/FormatHelper.jsp