前言
JSP自定义标签(JSP Custom Tag)可以让开发者在JSP页面中自定义标签,这些标签与JSP标准标签有着相同的作用,但更加灵活和易于维护。开发者可以使用JSP标准标签库或者自定义标签库在JSP中实现更加高效、可重用的代码。
目录
TLD文件理解
- short-name: 标签前缀:类比C标签的c:if》c
- tag-class:页面渲染时处理标签的工作类
- name:标签后缀名:类比C标签的c:if》if
- body-content:主体内容:
- jsp:接收所有的jsp语法的内容
- empty:开始和结束中间没有内容
- scriptless:接收文本、el和jsp脚本
- agDependent:标签体内容直接写入bodyContext由自定义标签类进行处理
- attribute:标签的属性,类比input标签的name/value等属性
- name:属性名(与标签处理类的属性(set)必须保持一致)
- required:属性的必要性
- rtexprvalue:是否支持特殊表达式:EL表达式等
JSP自定义标签的生命周期
(1)doStartTag() 处理开始标签的方法
(2)doAfterBody()计算主体的方法
(3)doEndTag()处理结束标签的方法(其实可以不用写的它是默认的)
JSP自定义标签的开发以及使用步骤(foreach为例子)
创建一个标签助手类(继承BodyTagSupport)
标签属性必须助手类的属性对应、且要提供对应get/set方法
重写三个方法
- doStartTag() 处理开始标签的方法
- doAfterBody()计算主体的方法
- doEndTag()处理结束标签的方法(其实可以不用写的它是默认的)
package Entity;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
/**
* foreach 标签分析得知会有两个属性
* items list<Object>
* var String
* 分析路线:
*
*
*
*/
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForeachTag extends BodyTagSupport {
private List<?> items;
private String var;
public List<?> getItems() {
return items;
}
public void setItems(List<?> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doStartTag() throws JspException {
//遍历集合
Iterator<?> it = items.iterator();
//将遍历的每一个对象,设置到var命名中
pageContext.setAttribute(var, it.next());
//为了保留迭代时指针现有的位置
pageContext.setAttribute("iterator", it);
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
//先拿到迭代器
Iterator<Object> it = (Iterator<Object>) pageContext.getAttribute("iterator");
//如果有下一个,进入循环
if(it.hasNext()) {
//将遍历的每一个对象,设置到var命名中
pageContext.setAttribute(var, it.next());
//为了保留迭代时指针现有的位置
pageContext.setAttribute("iterator", it);
return EVAL_BODY_AGAIN;
}else {
return EVAL_PAGE;
}
}
}
了解助手类里面常量的意思
- SKIP_BODY:跳过主体
- EVAL_BODY_INCLUDE:计算标签主体内容并[输出]
- EVAL_PAGE:计算页面的后续部分
- SKIP_PAGE:跳过页面的后续部分
- EVAL_BODY_AGAIN:再计算主体一次
创建tld文件
<taglib>
<description>JSTL 1.1 core library</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<!-- 一个名字 -->
<short-name>t</short-name>
<!-- 路径 -->
<uri>http://jsp.tgq.cn</uri>
<tag>
<name>foreach</name>
<tag-class>Entity.ForeachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<requiredvalue>true</requiredvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
</tag>
</taglib>
在页面中使用自定义标签
然后跟使用c标签中的foreach一样操作就可以啦,这里就不做演示啦
例子自定义select标签
标签助手类
package Entity;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.beanutils.PropertyUtils;
import com.sun.org.apache.xml.internal.serializer.ToHTMLStream;
/**
* 分析,选择标签遍历
* @author liwen
*1、省略遍历的过程
*2、当作数据回显的时候,无序增加if判断,无序增加新的代码
*
*分析:
*1、后台需要遍历-数据源-itmes
*2、需要一个对象的属性,代表下拉框对应的展示内容
*3、需要一个对象的属性,代表下拉框的对应的value值
*4、默认的展示内容
*5、默认的选项值
*6、数据库中存储的值,为了方便做数据回显
*7、id
*8、name
*9、cssstyle
*/
public class SelectTag extends BodyTagSupport{
public List<?> getItems() {
return items;
}
public void setItems(List<?> items) {
this.items = items;
}
public String getTextVal() {
return textVal;
}
public void setTextVal(String textVal) {
this.textVal = textVal;
}
public String getTextkey() {
return textkey;
}
public void setTextkey(String textkey) {
this.textkey = textkey;
}
public String getHearderTextvalue() {
return hearderTextvalue;
}
public void setHearderTextvalue(String hearderTextvalue) {
this.hearderTextvalue = hearderTextvalue;
}
public String getHearderTextkey() {
return hearderTextkey;
}
public void setHearderTextkey(String hearderTextkey) {
this.hearderTextkey = hearderTextkey;
}
public String getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(String selectedValue) {
this.selectedValue = selectedValue;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private List<?> items;
private String textVal;
private String textkey;
private String hearderTextvalue;
private String hearderTextkey;
private String selectedValue;
private String id;
private String name;
@Override
public int doStartTag() throws JspException {
//拿到io流
JspWriter out = pageContext.getOut();
try {
out.print(toHTML());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.doStartTag();
}
private String toHTML() throws Exception {
StringBuffer sb= new StringBuffer();
sb.append("<select id='"+id+"' name='"+name+"'>");
if(hearderTextvalue !=null && ! "".equals(hearderTextvalue)) {
sb.append("<option value='"+hearderTextkey+"'>"+hearderTextvalue+"</option>");
}
for (Object obj :items) {
Field textkeyfiled = obj.getClass().getDeclaredField(textkey);
//打开访问权限
textkeyfiled.setAccessible(true);
Object value = textkeyfiled.get(obj);
if(selectedValue !=null && !"".equals(selectedValue) && selectedValue.equals(value)) {
sb.append("<option selected value='"+value+"'>"+PropertyUtils.getProperty(obj,textVal )+"</option>");
}else {
sb.append("<option value='"+value+"'>"+PropertyUtils.getProperty(obj,textVal )+"</option>");
}
}
sb.append("</select>");
return sb.toString();
}
}
TLD文件
<taglib >
<description>JSTL 1.1 core library</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<!-- 一个名字 -->
<short-name>t</short-name>
<!-- 路径 -->
<uri>http://jsp.tgq.cn</uri>
<tag>
<name>foreach</name>
<tag-class>Entity.ForeachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<requiredvalue>true</requiredvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
</tag>
<tag>
<name>select</name>
<tag-class>Entity.SelectTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<requiredvalue>true</requiredvalue>
</attribute>
<attribute>
<name>textVal</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
<attribute>
<name>textVkey</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
<attribute>
<name>headerTextvalue</name>
<required>false</required>
<requiredvalue>false</requiredvalue>
</attribute>
<attribute>
<name>headerTextkey</name>
<required>false</required>
<requiredvalue>false</requiredvalue>
</attribute>
<attribute>
<attribute>
<name>selectedValue</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
<name>id</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
<requiredvalue>false</requiredvalue>
</attribute>
</tag>
</taglib>
页面引用
<%@taglib prefix="" uri="h"%>//引如taglib
//使用标签
<h:select items="${selectlist }" optionVal="cid" optionText="cname"
optionSelect="2"></h:select>
ok,今天的内容就到这里结束啦