1.我们要知道自定义标签开发步骤离不开这三个步骤:
1.1 助手类
1.2 tld
1.3 taglib
2.在c标签大致分为UI标签,控制标签,数据标签
2.1 接下来我会一一分析这三个=种标签
UI标签
就是我们展示在界面的内容,用ui标签也就是不需要写标签体的标签又能展示内容的就是ui标签 注1:JspWriter writer = pageContext.getOut();
控制标签
我们看到控制就可以判断,他是会控制文本,标签等的一类,包括是否展示,条件的改变等。注1:page(pageContext)|request(…)|session(…)|application(…)
存储和交换数据
数据标签
数据标签就是用来存储数据的 “比如set标签”
接下来,我们主要分析set和out标签,if标签,foreach标签和select 标签的开发。
1.set标签和out标签
1.1 set助手类
这个是我配置set属性的代码
<tag>
<name>set</name>
<tag-class>com.liuxia.jsp.day02.SetTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!-- 该标签的属性 -->
<name>var</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>value</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
1.2 out助手类
这个是我配置set,out属性的代码
<tag>
<name>out</name>
<tag-class>com.liuxia.jsp.day02.OutTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!-- 该标签的属性 -->
<name>value</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
下面是我们的jsp界面的out,set的测试代码以及结果
运行结果:
、
if标签
1.2 if助手类
这个是我配置if属性的代码
<tag>
<name>if</name>
<tag-class>com.liuxia.jsp.day02.IfTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!-- 该标签的属性 -->
<name>test</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
下面是我们的jsp界面的out,set的测试代码以及结果
运行结果:
foreach标签
1.2 foreach助手类
package com.liuxia.jsp.day02;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* c:foreach
* var 指针
* it
* @author 2018120102
*
*/
public class ForeachTag extends BodyTagSupport {
private static final long serialVersionUID = 3114725354266258520L;
private String var;
private List<Object> items=new ArrayList<>();
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
@Override
public int doStartTag() throws JspException {
Iterator<Object> it = items.iterator();
//默认指针存放是位置是没有指向对象的,现在需要指向对象,那么需要指针下移
pageContext.setAttribute(var, it.next());
//因为集合元素较多,那么指针需要循环的向下移动,那么我们需要将迭代器保存,用于下一次指针下移所用
pageContext.setAttribute("it",it);
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
//获取已经保存了迭代器
Iterator<Object> it= (Iterator<Object>)pageContext.getAttribute("it");
if(it.hasNext()) {
//指针下移指向新的元素
pageContext.setAttribute(var, it.next());
//再保存正在使用的迭代器
pageContext.setAttribute("it", it);
return EVAL_BODY_AGAIN;
}else {
return EVAL_PAGE;
}
}
}
这个是我配置foreach属性的代码
下面是我们的jsp界面的foreach的测试代码以及结果
运行结果:
select 标签
1.2 select助手类
package com.liuxia.jsp.day02;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
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.BeanUtils;
/**
* <select id='' name=''>
* <option value='-1' selected>====</option>
* </select>
* @author 2018120102
* 查询维度;下拉列表
* 修改页面:下拉列表 数据回显
*
* 1 id name
* 2.数据源items, 存入数据库中的值textKey, 展示列textVal
* 3.加入属性(默认的头部属性值headTextKey,默认的展示列值 headTextVal)
* 4.加入属性,能够实现数据回显的功能selectedVal
*/
public class SelectTag extends BodyTagSupport {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private List<Object> items=new ArrayList<Object>();
private String textKey;
private String textVal;
private String headTextKey;
private String headTextVal;
private String selectedVal;
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;
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getTextKey() {
return textKey;
}
public void setTextKey(String textKey) {
this.textKey = textKey;
}
public String getTextVal() {
return textVal;
}
public void setTextVal(String textVal) {
this.textVal = textVal;
}
public String getHeadTextKey() {
return headTextKey;
}
public void setHeadTextKey(String headTextKey) {
this.headTextKey = headTextKey;
}
public String getHeadTextVal() {
return headTextVal;
}
public void setHeadTextVal(String headTextVal) {
this.headTextVal = headTextVal;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.write(toHTML());
} catch (Exception e) {
e.printStackTrace();
}
return super.doStartTag();
}
/**
* 拼接出下列表所对应的select的html代码
* <select id='' name=''>
* <option value='-1' selected>===请选择====</option>
* </select>
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws NoSuchMethodException
* @throws InvocationTargetException
*/
private String toHTML() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
StringBuilder sb=new StringBuilder();
sb.append("<select id='"+id+"' name='"+name+"'>");
if(!(headTextKey==null||"".equals(headTextKey)|| headTextVal==null||"".equals(headTextVal))) {
sb.append(" <option value='"+headTextKey+"' selected>"+headTextVal+"</option>");
}
String val;
String html;
for (Object obj : items) {
//要让学生id存入数据,让学生的名字展示在jsp页面
Field textKeyField = obj.getClass().getDeclaredField(textKey);
textKeyField.setAccessible(true);
val= (String) textKeyField.get(obj);
html=BeanUtils.getProperty(obj, textVal);
if(val.equals(selectedVal)) {
sb.append("<option value='"+val+"'>"+html+"</option>");
}else {
sb.append("<option value='"+val+"'>"+html+"</option>");
}
}
sb.append("</select>");
return sb.toString();
}
}
这个是我配置select属性的代码
<tag>
<name>select</name>
<tag-class>com.liuxia.jsp.day02.SelectTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!-- 该标签的属性 -->
<name>id</name>
<!-- 该属性是否必填 -->
<required>false</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>name</name>
<!-- 该属性是否必填 -->
<required>false</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>items</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>textKey</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>textVal</name>
<!-- 该属性是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>headTextKey</name>
<!-- 该属性是否必填 -->
<required>false</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>headTextVal</name>
<!-- 该属性是否必填 -->
<required>false</required>
<!-- 是否支持表达式 -->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<!-- 该标签的属性 -->
<name>selectedVal</name>
<!-- 该属性是否必填 -->
<required>false</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
下面是我们的jsp界面的select的测试代码以及结果
运行结果: