做了个简单的实验:写一个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. [转]SSIS高级转换任务—行计数

    本文转自:http://www.cnblogs.com/tylerdonet/archive/2011/06/19/2084780.html 在SSIS中的Row Count转换可以在数据流中计算数据 ...

  2. 向PE文件植入后门代码技术讨论

    写在前面的话 这篇文章将介绍使用codecaves对PE文件植入后门代码.有几个很好的工具可以帮到你了.比如BackdoorFactory和Shelter将完成相同的工作,甚至绕过一些静态分析几个防病 ...

  3. 【算法导论C++代码】最大子数组

    #define Inf 65535 #include <iostream> using namespace std; void FindMaxCrossingSubarray(int *A ...

  4. Vue侦听器watch

    虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器.这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化.当需要在数据变化时执行异步或开销较大的操作时,这 ...

  5. HDU5312 Sequence

    题意:t组数据,每组数据给个m.问m最少能由几项形如3*n*(n-1)+1的数表示 eg 7=1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1);     ...

  6. 转:超实用的IOS 9人机界面指南(1):UI设计基础 (腾讯力作)

    转: http://www.uisdc.com/ios9-interface-guideline-ui

  7. 搭建dubbo-admin-2.5.3

    dubbo管理界面 一,安装zookeeper 1,下载包zookeeper-3.3.3.tar.gz 2,解压 tar zxvf zookeeper-3.3.3.tar.gz cd zookeepe ...

  8. node了解

    学习资料 廖雪峰的官方网站—node.js Node.js 中文网:http://nodejs.cn/ Node.js 教程(菜鸟教程):http://www.runoob.com/nodejs/no ...

  9. Android 如何在关于手机界面添加个图片

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  10. vue - src(assets和static)

    描述:这里存放一些本地资源(images.css.js). assets:开发服务器(dev Server时引用的临时路径) static:静态资源存放(build Server).