关于自定义标签的属性设置问题

本文详细介绍了JSP自定义标签的应用,包括标签处理器类的属性设置、标签库描述文件的定义、标签在JSP页面中的使用方法等。特别探讨了不同类型属性值的处理方式及其在EL表达式中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用到JSP中的自定义标签技术时,关于自定义标签对应的处理器类的属性设置:如果属性类型是基本类型,JSP容器可以自动完成类型转换,并调用符合Bean标准的setter方法。

例如:我们定义一个简单的标签处理器类FirstPersonTag,它负责向JSP页面输出一段信息,包括他自己的名字、年龄、性别。

package com.neuqsoft.demo.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class FirstPersonTag extends SimpleTagSupport{
	private String name;
	private int age;
	private boolean male;
	public void setAge(int age) {
		this.age = age;
	}
	public void setMale(boolean male) {
		this.male = male;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void doTag() throws JspException, IOException {
		super.doTag();
		JspWriter out=getJspContext().getOut();
		out.println("Name:"+name);
		out.println("Age:"+age);
		out.println("Sex:"+(male?"Male":"Female"));
	}
} 

下面是它所在的标签库描述文件demo1.tld的定义:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
  <tlib-version>1.1</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>Demo</short-name>
  <uri>http://demo1.neuqsoft.com</uri>
  <display-name>Neuqsoft CustomTag Demo</display-name>
  <description>Demo</description>
  <tag>
    <name>firstPerson</name>
    <tag-class>com.neuqsoft.demo.tag.FirstPersonTag</tag-class>
    <body-content>NONE</body-content>
    <display-name>table</display-name>
    <description>The First PersonTag</description>
    <attribute>
      <name>name</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The name of this Person</description>
    </attribute>
    <attribute>
      <name>age</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The age of this Person</description>
    </attribute>
    <attribute>
      <name>male</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The sex of this Person</description>
    </attribute>
  </tag>
</taglib>

firstPerson标签在JSP页面中的使用方法:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" pageEncoding="gb2312"%>
<%@ taglib uri="http://demo1.neuqsoft.com" prefix="demo"%>
<html>
  <head>
    <title>自定义标签演示</title>
  </head>
  <body>
  	<demo:firstPerson name="Flixy" age="26" male="false"></demo:firstPerson>
  </body>
</html> 

上面代码的输出结果为 :Name:Flixy Age:26 Sex:Female

如果注意demo1.tld的内容的话,可以看到每一个属性定义(<attribute>元素)中都有<rtexprvalue>true</rtexprvalue>被指定,rtexprvalue实际上是Runtime Expression Value的所写,如果它的值为true,说明此属性值可以接受一个EL表达式。因此对于firstPerson这个标签我们还可以这样使用。

firstPerson标签在JSP页面中的使用方法2:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" pageEncoding="gb2312"%>
<%@ taglib uri="http://demo1.neuqsoft.com" prefix="demo"%>
<html>
  <head>
    <title>自定义标签演示</title>
  </head>
  <body>
  	<%
  		request.setAttribute("age",new Integer(25));
  		request.setAttribute("male",Boolean.valueOf(true));
  	%>
  	<demo:firstPerson name="Flixy" age="${age}" male="${male}"></demo:firstPerson>
  </body>
</html> 

上面代码的输出结果为 :Name:Flixy Age:25 Sex:Male

注意:实际应用中request的属性对应该是在Action中设置的,JSP页面作为视图层只负责展现数据。

但是你可能认为上面两个例子演示的使用EL表达式与否并无本质的差异,相反使用EL表达式倒显得笨拙一些,但是考虑如下的情形,假如标签处理器类中的属性不是基本类型呢?这个时候JSP容器是无法完成转换的,因为属性的类型很可能是你自己定义的。不妨看下面的例子,在这个例子中Person的性别我们不是用一个boolean值表示,而是用一个自定义的对象Sex,Sex的源码如下:

package com.neuqsoft.demo.tag;

public class Sex{
	private boolean isMale;
	
	public Sex(boolean isMale) {
		super();
		this.isMale = isMale;
	}

	public boolean isMale() {
		return isMale;
	}

	public void setMale(boolean isMale) {
		this.isMale = isMale;
	}
} 

下面是Person标签处理器类的第二个版本:

package com.neuqsoft.demo.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SecondPersonTag extends SimpleTagSupport {
	private String name;
	private int age;
	private Sex sex=new Sex(false);
	public void setAge(int age) {
		this.age = age;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setSex(Sex sex) {
		this.sex = sex;
	}
	public void doTag() throws JspException, IOException {
		super.doTag();
		JspWriter out=getJspContext().getOut();
		if(sex==null)sex=new Sex(true);
		out.println("Name:"+name);
		out.println("Age:"+age);
		out.println("Sex:"+(sex.isMale()?"Male":"Female"));
	}
} 

其对应的标签定义片段:

<tag>
    <name>secondPerson</name>
    <tag-class>com.neuqsoft.demo.tag.SecondPersonTag</tag-class>
    <body-content>NONE</body-content>
    <display-name>table</display-name>
    <description>The First PersonTag</description>
    <attribute>
      <name>name</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The name of this Person</description>
    </attribute>
    <attribute>
      <name>age</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The age of this Person</description>
    </attribute>
    <attribute>
      <name>sex</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The sex of this Person</description>
    </attribute>
</tag> 

由于SecondPersonTag的setSex方法的参数不是基本类型而是Sex,所以JSP容器不能自动完成类型转换,在这种情况下只能使用EL 表达式了,如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" import="com.neuqsoft.demo.tag.Sex" pageEncoding="gb2312"%>
<%@ taglib uri="http://demo1.neuqsoft.com" prefix="demo"%>
<html>
  <head>
    <title>自定义标签演示</title>
  </head>
  <body>
  	<%request.setAttribute("sex",new Sex(true)); %>
  	<demo:secondPerson name="Flixy" age="75" sex="${sex}"></demo:secondPerson>
  </body>
</html> 

显示结果:Name:Flixy Age:75 Sex:Male

使用内省,如果标签处理器类中没有符合Javabean规范的setter方法,可以使用内省告诉JSP容器怎么处理标签的属性赋值,这需要额外提供一个BeanInfo类,此类和标签处理器类在同一个包中,命名规则是标签处理器类类名+BeanInfo,例如假如标签处理器的完整类名为com.neuqsoft.demo.PersonTag,则BeanInfo类的完整类名应该是com.neuqsoft.demo.PersonTagBeanInfo,下面是一个例子,例子中是PersonTag的第三个版本ThirdPersonTag:

package com.neuqsoft.demo.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ThirdPersonTag extends SimpleTagSupport{
	private String name;
	private int age;
	private Sex sex;
	
	public void sex(Sex _sex){
		this.sex=_sex;
	}
	
	public void setName(String name){
		this.name=name;
	}
	
	public void putAge(int age){
		this.age=age;
	}
	
	public void doTag() throws JspException, IOException {
		super.doTag();
		JspWriter out=getJspContext().getOut();
		if(sex==null)sex=new Sex(true);
		out.println("Name:"+name);
		out.println("Age:"+age);
		out.println("Sex:"+(sex.isMale()?"Male":"Female"));
	}
} 

其对应的标签定义片段:

<tag>
    <name>thirdPerson</name>
    <tag-class>com.neuqsoft.demo.tag.ThirdPersonTag</tag-class>
    <body-content>NONE</body-content>
    <display-name>table</display-name>
    <description>The First PersonTag</description>
    <attribute>
      <name>_name</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The name of this Person</description>
    </attribute>
    <attribute>
      <name>_age</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The age of this Person</description>
    </attribute>
    <attribute>
      <name>_sex</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      <description>The sex of this Person</description>
    </attribute>
</tag> 

注意:我故意在每一个属性name值前面加上了下划线,例如_name、_age、_sex,显然ThirdPersonTag这个标签处理器类中没用对应的setter方法,那么我是如何告诉JSP容器找到合适的方法设置属性值的呢?答案是BeanInfo类,下面是ThirdPersonTagBeanInfo类的源码:

package com.neuqsoft.demo.tag;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
import java.util.ArrayList;
import java.util.List;

public class ThirdPersonTagBeanInfo extends SimpleBeanInfo {
	public PropertyDescriptor[] getPropertyDescriptors() {
		List proplist = new ArrayList();
		try {
			proplist.add(new PropertyDescriptor("_sex",ThirdPersonTag.class,null,"sex"));
			proplist.add(new PropertyDescriptor("_age",ThirdPersonTag.class,null,"putAge"));
			proplist.add(new PropertyDescriptor("_name",ThirdPersonTag.class,null,"setName"));
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		return (PropertyDescriptor[]) proplist.toArray(new PropertyDescriptor[0]);
	}
} 

它的getPropertyDescriptors返回一组属性描述符,描述了每一个属性应该被怎样设置到标签处理器类中,例如_age属性对应着putAge方法,尽管这个方法不符合Javabean的setter方法规范。

ThirdPersonTag应用示例

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" import="com.neuqsoft.demo.tag.Sex" pageEncoding="gb2312"%>
<%@ taglib uri="http://demo1.neuqsoft.com" prefix="demo"%>
<html>
  <head>
    <title>自定义标签演示</title>
  </head>
  <body>
  	<%request.setAttribute("sex",new Sex(true)); %>
  	<demo:thirdPerson _name="FlixyDemo3" _age="75" _sex="${sex}"></demo:thirdPerson>
  </body>
</html> 

显示结果:Name:FlixyDemo3 Age:75 Sex:Male

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值