jsp自定义标签

来源:互联网 发布:什么是淘宝联盟 编辑:程序博客网 时间:2024/05/16 06:45

自定义标签:

三个步骤:1java的实现类继承TagSupport ,BodyTagSupport 或者simpleTagSupport

       2*.tld的标签文件的配置 ,位置在WEB-INF下面 

          3,(可选)web.xml中的标签的名字配置

          4, 页面的引入

第一个简单的标签:

·实现类:

public class Tag1 extends TagSupport{

//<a>-->标签的开始  </a>--->标签的结束

 public int doStartTag(){

JspWriter out = super.pageContext.getOut();

try {

out.print("<b>hello!world</b>");

catch (IOException e) {

e.printStackTrace();

}

return SKIP_BODY;

}

}

·标签文件

<tag>

<name>showHello</name> //这个就相当于<c:forEach>

<tag-class>myTag.Tag1</tag-class>

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

</tag>

·web.xml中(可选)

 <jsp-config>

   <taglib>

   <taglib-uri>firstTag</taglib-uri> 

//下面是指定.tld文件的位置

   <taglib-location>/WEB-INF/mytld.tld</taglib-location>

   </taglib>

</jsp-config>

·jsp页面:

//如果是配置了web.xml的话

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

//没有配置web.xml

<%@ taglib prefix="firstTag" uri="/WEB-INF/mytld.tld"%>

针对有属性的自定义标签:

java实现类:

public class DateFormat extends TagSupport{

private String formatString ; //利用反射机制调用setter方法来赋值

public String getFormatString() {

return formatString;

}

public void setFormatString(String formatString) {

this.formatString = formatString;

}

@Override

public int doStartTag() throws JspException {

SimpleDateFormat simpleDateFormat= new SimpleDateFormat(formatString);

Date date = new Date();

String dateString = simpleDateFormat.format(date);

try {

super.pageContext.getOut().print(dateString);

catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return SKIP_BODY; //跳过标签体

}

}

标签文件:

<tag>

<name>dateFormat</name> //这个就相当于<c:forEach>

<tag-class>myTag.DateFormat</tag-class>

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

<attribute>

<name>formatString</name> //这个名字要和java类中的字段一样

<required>true</required> //此属性一定要设置

<rtexprvalue>true</rtexprvalue> //是否接受表达式

</attribute>

</tag>

对于web.xml和页面的设置和上面是一样的

TagSuper:

· EVAL_BODY_INCLUDE(执行标签体内的内容)

·EVAL_PAGE  执行jsp页面

·SKIP_BODY 跳过标签体

·SKIP_PAGE 结束jsp页面

判断自定义标签

实现类中这样写:

public int doStartTag() throws JspException {

if(num > 0){

return EVAL_BODY_INCLUDE;

}

return SKIP_BODY;

}

其他的跟上面的列子一样的

迭代自定义标签

页面代码:

<my:loop var="s" name="list" scope="request">

${s }

</my:loop>

实现类:

public class LoopTag extends TagSupport {

private String name//可以把这个字段名看做是jsp页面里面的字段里面的值

private String scope//是通过反射setter来赋值的

private String var;//对于循环的每一个对象

//这个是个很重要的东西,这个不需要getter和setter方法

//迭代器,用来判断是否有下一个

private Iterator iterator ; 

public int doStartTag() throws JspException {

Object val = null;

if("request".equalsIgnoreCase(scope)){

val = super.pageContext.getAttribute(this.name,PageContext.REQUEST_SCOPE);

}

if(val != null && val instanceof List<?>){

iterator = ((List<?>)val).iterator(); //这里要注意,把list转变为迭代器,以为要判断下一个是否存在

if (iterator.hasNext()) {//***这里不是while,是if,只需要判读一次

super.pageContext.setAttribute(this.var, iterator.next()); //把val存放到页面中名字为var的值的对象*******

return EVAL_BODY_INCLUDE;  //执行body里面的代码  ${..}

}else {

return SKIP_BODY;

}

}else {

return SKIP_BODY;

}

}

@Override

public int doAfterBody() throws JspException {

if (iterator.hasNext()) { //如果还有下一个,就重复执行body里面

super.pageContext.setAttribute(this.var, iterator.next());//oooreturn EVAL_BODY_AGAIN;

}else {

return SKIP_BODY;

}

}

....setter getter方法

}

BodyTagSupport

public class BodyTagSupport extends TagSupport implements BodyTag

BodyTagSupportTagSupport的不同就是它可以得到标签体里面的内容,在BodyTagSupport里面得到标签体里面的内容是getBodyContent().getString();且要写在doAfterTagSupport()里面,

TagSupport里面得到输出流是pageContext.getOut();

BodyTagSupport里面需要getPreviousOut();来得到

例子:大写的转换

public int doAfterBody() throws JspException {

--count;

if(count > 0){

//得到标签里面的内容,getBodyContent().getString()这个要写到doAfterBody()里面

String content = getBodyContent().getString();

if(content!=null){

String upContent = content.toUpperCase();

try {

//得到输出流

this.getPreviousOut().print(upContent);

catch (IOException e) {

e.printStackTrace();

}

}

return EVAL_BODY_AGAIN;

}else{

return SKIP_BODY;

}

}

SimpleSupport

对于SimpleSupportTagSupportBodyTagSupport的不同就是,SimpleSupport简化了一下操作,它只要重新doTag() 就可以了,SimpleSupport是通过getJspContext()来得到隐士对象的,相当于TagSupportpageContext,通过getJspBody来的的标签体对象

迭代的例子:(其他部分都跟上面的的相同)

public void doTag() throws javax.servlet.jsp.JspException ,java.io.IOException {

 Object value = this.getJspContext().getAttribute(name,PageContext.REQUEST_SCOPE);

if(value != null && value instanceof List<?>){

iterator = ((List<?>)value).iterator();

while (iterator.hasNext()) {

    this.getJspContext().setAttribute(this.variterator.next());

//执行标签里面的内容,null意思就是知识执行标签里面生成的内容

super.getJspBody().invoke(null); //执行${ },因为在上面已经设置了值

}

}

};

配置文件:

 <tag>

   <name>loop</name>

   <tag-class>myTag.LoopTag</tag-class>

   <body-content>scriptless</body-content>

   <attribute>

    <name>name</name>

   <required>true</required>

   <rtexprvalue>true</rtexprvalue>

   </attribute>

   <attribute>

    <name>scope</name>

   <required>true</required>

   <rtexprvalue>true</rtexprvalue>

   </attribute>

   <attribute>

    <name>var</name>

   <required>true</required>

   <rtexprvalue>true</rtexprvalue>

   </attribute>

  </tag>

日期转换:

@Override

public void doTag() throws JspException, IOException {

SimpleDateFormat sd = new SimpleDateFormat(format);

String dateString = sd.format(new Date());

getJspContext().getOut().print(dateString);

}

动态属性():