做了个简单的实验:写一个tag,将tag body中的内容打印成一个三角形

代码很简单就不赘述了,直接贴在下面,值得注意的是这个图(摘自李兴华JAVA开发实战经典)

在做的过程中遇到了如下问题:

1. getBodyContent()返回null

  原因:doStartTag()应该返回EVAL_BODY_BUFFERED而不是EVAL_BODY_INCLUDE,否则bodyContent在doAfterBody()中是不可见的

2. pageContext.getOut().println()无法向页面输出内容

  原因:bodyContent本身就是一个JspWriter,应该使用BodyTagSupport.getPreviousOut().println()进行输出

  关于这个问题,参考此页面 http://www.coderanch.com/t/175316/java-Web-Component-SCWCD/certification/BodyTag-getPreviousOut-getPageContext-getOut

  

代码如下,这个Tag有一个可选参数:size,表示三角形的大小

FunnyTriangleTag.java

public class FunnyTriangleTag extends BodyTagSupport {
private static final int DEFAULT_SIZE = 2;
private int size = -1; public int getSize() {
return size;
} public void setSize(int size) {
this.size = size;
} private int count = 0; @Override
public int doStartTag() throws JspException {
if (size < DEFAULT_SIZE) {
count = DEFAULT_SIZE;
} else {
count = size;
}
return EVAL_BODY_BUFFERED;
} @Override
public int doAfterBody() throws JspException {
if (count-- > 0) {
try {
String string = this.getBodyContent().getString();
this.getPreviousOut().println("<p>"+string+"</p>");
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_BODY_AGAIN;
} else {
return SKIP_BODY;
}
} @Override
public int doEndTag() throws JspException {
size = -1;
count = 0;
return EVAL_PAGE;
} }

index.jsp

<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<%@ taglib uri="http://tags.xxx.com/foo" prefix="foo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Insert title here</title>
</head>
<body>
<foo:funnyTriangle size="5">你好</foo:funnyTriangle>
<foo:funnyTriangle>默认1</foo:funnyTriangle>
<foo:funnyTriangle size="-1">默认2</foo:funnyTriangle>
</body>
</html>

foo.tld

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

<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"> <description>xxx's foo tags</description>
<display-name>xxx foo tags</display-name>
<tlib-version>1.0</tlib-version>
<short-name>foo</short-name>
<uri>http://tags.xxx.com/foo</uri> <tag>
<description>Print the string in the tag body repeatedly to form a triangle shape.</description>
<name>funnyTriangle</name>
<tag-class>com.v1.ex118.FunnyTriangleTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<description>
The size of the triangle, no less than 2. If the size is less
than 2, a default-sized triangle will be displayed.
</description>
<name>size</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue> <!-- support EL -->
<type>java.lang.Integer</type>
</attribute>
</tag>
</taglib>

BodyTagSupport小案例1的更多相关文章

  1. 机械表小案例之transform的应用

    这个小案例主要是对transform的应用. 时钟的3个表针分别是3个png图片,通过setInterval来让图片转动.时,分,秒的转动角度分别是30,6,6度. 首先,通过new Date函数获取 ...

  2. shell讲解-小案例

    shell讲解-小案例 一.文件拷贝输出检查 下面测试文件拷贝是否正常,如果cp命令并没有拷贝文件myfile到myfile.bak,则打印错误信息.注意错误信息中basename $0打印脚本名.如 ...

  3. [jQuery学习系列六]6-jQuery实际操作小案例

    前言最后在这里po上jQuery的几个小案例. Jquery例子1_占位符使用需求: 点击第一个按钮后 自动去check 后面是否有按钮没有选中, 如有则提示错误消息. <html> &l ...

  4. 02SpringMvc_springmvc快速入门小案例(XML版本)

    这篇文章中,我们要写一个入门案例,去整体了解整个SpringMVC. 先给出整个项目的结构图:

  5. React.js入门小案例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  6. SqlDependency缓存数据库表小案例

    SqlDependency的简介: SqlDependency是outputcache网页缓存的一个参数,它的作用是指定缓存失效的数据库依赖项,可以具体到数据库和表. SqlDependency能解决 ...

  7. JavaScript apply函数小案例

    //回调函数1 function callback(a,b,c) { alert(a+b+c); } //回调函数2 function callback2(a,b) { alert(a+b); } / ...

  8. Session小案例------完成用户登录

    Session小案例------完成用户登录     在项目开发中,用户登陆功能再平常只是啦,当用户完毕username和password校验后.进入主界面,须要在主界面中显示用户的信息,此时用ses ...

  9. ch1-vuejs基础入门(hw v-bind v-if v-for v-on v-model 应用组件简介 小案例)

    1 hello world 引入vue.min.js 代码: ----2.0+版本 <div id="test"> {{str}} </div> <s ...

随机推荐

  1. python升级导致yum命令无法使用的解决办法?

    yum是依赖特定的python版本的,不同的linux系统需要的python版本不同. 查看yum的启动脚本:which is yum 头一行指定使用的python版本,这个必须是系统需要的,而不要使 ...

  2. nginx安装和配置

    一.安装:yum install nginx service nginx restart/start/check/status/... 二.配置:官网文档 http://nginx.org/en/do ...

  3. 用于OpenRISC的Makefile示例

    #* #*********************************************************************************************** ...

  4. Spring与Quartz的整合

    Quartz Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制.Quartz允许开发人员根据时间间隔来调度作业.它实现了作业和触发器的多 ...

  5. 多站点IIS用户安全权限设置

    如果我们为每个站点都建立一个用户,并设置该用户只有访问本站点的权限,那么就能将访问权限控制在每个站点文件夹内,旁注问题也就解决了 一.这样配置的好处? 不知大家有没有听过旁注?我简单的解释一下吧:有个 ...

  6. C# Json 序列化和反序列化 工具类 Newtonsoft.Json.dll

    引用: Newtonsoft.Json.dll // 引用: using Newtonsoft.Json; using Newtonsoft.Json.Converters; // 定义 实体测试类 ...

  7. 转:ios review推送与执行

    http://mp.weixin.qq.com/s?__biz=MzA4ODk0NjY4NA==&mid=409082578&idx=1&sn=2ca1e453d3c21caa ...

  8. log4j实现每一个线程保存一个日志文件

    log4j.properties: ### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.Conso ...

  9. set_exception_handler 自定义异常处理

    该函数用于创建运行时期间的用户自己的异常处理方法. set_exception_handler(error_function) 参数 必需.规定未捕获的异常发生时调用的函数. 该函数必须在调用 set ...

  10. SOA初探

    背景 曾今SOA的概念犹如今日“云计算.大数据”一样,被炒得火热,不少企业便纷纷响应,并宣称会拥抱和实施SOA.而事实上,业界出现了两种极端:一种是由于各类文章和书籍关于SOA的描述往往太过抽象,再加 ...