当前位置:网站首页>自定义forEach标签&&select标签实现回显数据
自定义forEach标签&&select标签实现回显数据
2022-07-23 05:40:00 【_Leaf1217】
目录
一、前言
1.1 前言:
上上次文章我们一起探索了如何自定义Jsp标签,并且还一起实践了if、set以及out标签的制作;
而相信对于看了上上篇文章的伙伴们对于自定义标签已经是有了一些的了解跟实践,而Leaf今天这篇文章也就是想接着和大家一起来自定义两个标签:forEach&select,逐渐学会了自定义标签并且融洽实践后会对我们以后的开发中带来不小的帮助,可以节约不少的开发时间,好了,话不多说,开展我们的代码探索之旅吧!
二、自定义forEah标签
2.1 建立ForEachTag标签类,继承BodyTagSupport类
package com.leaf.tag;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* ForEach标签
* @author Leaf
*
* 2022年6月21日 上午8:37:51
*/
public class ForEachTag extends BodyTagSupport {
}2.2 分析ForEachTag标签的属性
/**
* ForEach标签
* <c:forEach items="${stus }" var="s">
* 分析会有两个属性:
* items:List<Object>
* var:String
* 分析线路返回值:
* 第二条:eval_body_include
* 第三条:eval_body_again
* @author Leaf
*
* 2022年6月21日 上午8:37:51
*/
2.3 编写ForEachTag标签类
根据forEach标签的特性,我们使用迭代器来进行遍历;
ForEachTag标签类完整代码:
package com.leaf.tag;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* ForEach标签
* <c:forEach items="${stus }" var="s">
* 分析会有两个属性:
* items:List<Object>
* var:String
* 分析线路返回值:
* 第二条:eval_body_include
* 第三条:eval_body_again
* @author Leaf
*
* 2022年6月21日 上午8:37:51
*/
public class ForEachTag extends BodyTagSupport {
private List<Object> items;//数据源
private String var;//代表数据源的每一个对象
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
//开始标签
@Override
public int doStartTag() throws JspException {
//迭代器
Iterator<Object> it = items.iterator();
//为了保留迭代时指针现有位置
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;
}
}
}2.4 配置上上篇文章建立的tld文件:Leaf.tld
<tag>
<name>forEach</name>
<tag-class>com.leaf.tag.ForEachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute></tag>
2.5 测试使用
<%
/* 测试forEach标签的数据源 */
List<Teacher> list = new ArrayList<Teacher>();
list.add(new Teacher("t001","元始天尊"));
list.add(new Teacher("t002","太上老君"));
list.add(new Teacher("t003","菩提老祖"));
/* 存到request里面 */
request.setAttribute("ts", list);
%>
<!-- 测试使用forEach标签 -->
<center>
<h2>测试ForEach标签</h2>
<table>
<l:forEach items="${ts }" var="t">
<tr>
<td>${t.tid }</td>
<td>${t.tname }</td>
</tr>
</l:forEach>
</table>
</center>2.6 运行页面

我们可以看到,ForEach标签定义成功啦!
三、自定义可遍历数据的select标签
首先还是建立SelectTag标签类,步骤都和上面的forEach标签一样,
所以属性分析什么的就直接放到代码顶部啦;
3.1 SelectTag标签类
package com.leaf.tag;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Properties;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.beanutils.PropertyUtils;
/**
* Select标签
* 1、省略遍历的过程;
* <l:select></l:select>--->实现遍历
* 2、当做数据回显时,无需增加if判断,无需增加新的代码。
* <l:select selectVal="t003" id="Myselect" headTextKey="-1" headTextVal="请选择" textVal="tname" items="${ts }" textKey="tid"></l:select>
*
* 分析属性:
* 1、后台要遍历--->数据源--->items
* 2、需要一个对象的属性代表下拉框对应的展示内容--->textVal--->展示的内容
* 3、需要一个对象的属性代表下拉框对应的value--->textKey--->value值
* 4、默认的头部选项--->headTextVal--->默认置顶的提示展示内容
* 5、默认的头部选项value--->headTextKey--->默认置顶的提示展示内容的value值
* 6、数据库中的值,方便做数据回显--->SelectVal
* 7、id--->标签的ID
* 8、name--->标签的name值
* 9、cssStyle
* @author Leaf
*
* 2022年6月21日 上午9:18:38
*/
public class SelectTag extends BodyTagSupport {
private List<Object> items;//数据源
private String textVal;//展示的内容
private String textKey;//value值
private String headTextVal;//默认置顶的提示展示内容
private String headTextKey;//默认置顶的提示展示内容的value值
private String SelectVal;//数据库中的值,方便做数据回显
private String id;//标签的ID
private String name;//标签的name值
@Override
public int doStartTag() throws JspException {
//拿到输出流out
JspWriter out = pageContext.getOut();
try {
//输送到页面
out.print(toHTML());
} catch (Exception e) {
e.printStackTrace();
}
return super.doStartTag();
}
private String toHTML() throws Exception {
StringBuffer sb = new StringBuffer();
sb.append("<select id='"+id+"' name='"+name+"'>");
if(headTextVal != null && !"".equals(headTextVal)) {
sb.append("<option value='"+headTextKey+"'>"+headTextVal+"</option>");
}
for (Object obj : items) {
//<l:select textVal="name" items="${ts }" textKey="tid"></l:select>
//拿到类类
Class<? extends Object> cl = obj.getClass();
Field textKeyfield = cl.getDeclaredField(textKey);
//打开访问权限
textKeyfield.setAccessible(true);
//拿到下拉框的value值
Object value = textKeyfield.get(obj);
if(SelectVal != null && !"".equals(SelectVal) && SelectVal.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();
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> 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 getHeadTextVal() {
return headTextVal;
}
public void setHeadTextVal(String headTextVal) {
this.headTextVal = headTextVal;
}
public String getHeadTextKey() {
return headTextKey;
}
public void setHeadTextKey(String headTextKey) {
this.headTextKey = headTextKey;
}
public String getSelectVal() {
return SelectVal;
}
public void setSelectVal(String selectVal) {
SelectVal = selectVal;
}
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;
}
}3.2 配置tld文件
<tag>
<name>select</name>
<tag-class>com.leaf.tag.SelectTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>textVal</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>textKey</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>headTextVal</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>headTextKey</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>selectVal</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute></tag>
3.3 测试使用
<style type="text/css">
/* select标签的样式 */
#Myselect {
color: purple;
}
</style>
<!-- 测试使用select标签 -->
<center>
<h2>测试select标签</h2>
<l:select selectVal="t003" id="Myselect" headTextKey="-1" headTextVal="请选择" textVal="tname" items="${ts }" textKey="tid">
</l:select>
</center>
selectVal就是判断是否选中的值,这里填写t003,代表的就是菩提老祖;
headTextVal就是默认的置顶提示的内容,headTextKey就是对应的value值;
textVal就是要遍历的属性名,textKey就是对应的value值;
3.4 运行页面

我们可以看到以往需要7~8行的代码经过我们自己定义的标签封装使用后只需要短短的一行,
并且匹配的selectVal也选中了!
OK,今天Leaf带来的ForEach标签以及便捷的select标签学习分享就到这里啦,还是老规矩,喜欢的可以关注一起学习咱们Java及其他的知识噢!后期还会有更多的学习分享~拜拜啦!!!
边栏推荐
- C语言之二分查找法或折半查找法剖析(经典例题,经典解析)
- Fun code rain, share it online~-
- IMG tag settings height and width are invalid
- npm init vite-app <project-name> 报错 Install for [‘[email protected]‘] failed with code 1
- [untitled]
- Use of views
- Spark常见面试问题整理
- Flask blueprint
- transform: translate(-50%, -50%)边框问题
- [监控部署实操]基于granfana展示Prometheus的图表和loki+promtail的图表
猜你喜欢

初识Flask

RPC与thrift入门

How pycharm packages OCR correctly and makes the packaged exe as small as possible

PyGame realizes the airplane war game

systemctl-service服务添加环境变量及模板

How to merge the website content with video and audio separated? How to write batch download code?

Niuke question brushing record -- MySQL
[email protected] ‘] failed with code 1"/>NPM init vite app < project name > error install for[‘ [email protected] ‘] failed with code 1

Py program can run, but the packaged exe prompts an error: recursion is detected when loading the "CV2" binary extension. Please check the opencv installation.
D2dengine edible tutorial (1) -- the simplest program
随机推荐
[部署]presto-server-0.261.tar.gz的集群部署和启动
TypeScript 常用类型
Niuke question brushing record -- MySQL
Project process summary
【Pyautogui学习】屏幕坐标、鼠标滚动
第一篇博客
[pytho-flask笔记5]蓝图简单使用
D2dengine edible tutorial (2) -- drawing images
First blog
C语言调试常见错误——简答
JS higher order function
[C language] what is a function? Classification and emphasis of functions (help you quickly classify and remember functions)
忽略埋点记录的ResizeObserver - loop limit exceeded
解决手动查询Oracle数据库时间格式不正确的问题(DATE类型)
[Doris]配置和基本使用contens系统(有时间继续补充内容)
Install pyGame using CMD
Error when PLSQL creates Oracle Database: when using database control to configure the database, it is required to configure the listener in the current Oracle home directory. You must run netca to co
When using cache in sprintboot, the data cannot be loaded
机器学习中的矩阵向量求导
Application of higher-order functions: handwritten promise source code (4)