javaWeb学习日记(12)----- 自定义标签

什么是自定义标签?
用户定义的一种自定义的jsp标记。当一个含有自定义标签的jsp页面被jsp引擎编译成servlet时, tag标签被转化成了对一个称为标签处理类的对象的操作。于是,当jsp页面被jsp引擎转化为servlet后,实际上tag标签被转化为了对tag处理类的操作。



传统标签和简单标签

  • 开发自定义标签,其核心就是要编写处理器类,一个标签对应-一个标签处理器类,而一个标签库则是很多标签处理器的集合。所有的标签处理器类都要实现JspTag接口,该接口中没有定义任何方法,主要作为Tag和SimpleTag接口的父接口。
  • 在JSP2.0以前,所有标签处理器类都必须实现Tag接口,这样的标签称为传统标签。
  • JSP 2.0规范又定义了一种新的类型的标签,称为简单标签,其对应的处理器类要实现 SimpleTag 接口

在这里插入图片描述
在这里插入图片描述



自定义标签的开发与应用步骤

  1. 编写完成标签功能的Java类(标签处理器)
  2. 编写标签库描述(tld)文件,在tld文件中对自定义中进行描述
  3. 在JSP页面中导入和使用自定义标签


范例

1. 实现标签 -athome:hello value=“athome” count=“10”-(打印 value 值 count 次)

java 类

public class SimpleTag implements javax.servlet.jsp.tagext.SimpleTag {
 //定义变量
 private String value;
 private String count;
 
 public void setValue(String value) {
  this.value = value;
 }
 
 private void setcount(String count) {
  this.count = count;
 }
 
 @Override
 public void doTag() throws JspException, IOException {
 
  //得到打印次数
  int countValue = Integer.parseInt(count);
  
  //得到 out 隐含变量
  JspWriter out = context.getOut();
  
  //循环打印
  for (int i = 0; i < countValue; i++) {
   out.println((i+1) + "," + value);
   out.println("<br>");
  }
 }
 
 @Override
 public JspTag getParent() {
  System.out.println("getParent");
  return null;
 }
 
 @Override
 public void setJspBody(JspFragment arg0) {
  System.out.println("setJspBody");
 }
 
 private PageContext context = null;
 @Override
 public void setJspContext(JspContext arg0) {
  System.out.println(arg0 instanceof PageContext);
  context = (PageContext) arg0;
  System.out.println("setJspContext");
 }
 
 @Override
 public void setParent(JspTag arg0) {
  System.out.println("setParent");
 }
}

tld文件中:

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">

    <!-- 描述tld 文件 -->
  <description>myTag 1.0</description>
  <display-name>myTag core</display-name>
  <tlib-version>1.0</tlib-version>

  <!-- 建议使用标签的前缀 -->
  <short-name>athome</short-name>
  <!-- 作为tid 文件的id,用来唯一标识当前的 tld 文件,多个tld 文件的uri 不能重复,通过 jsp 中的tablib 标签的 uri 来引用 -->
  <uri>http://www.athome.com/myTag/core</uri>

  <!-- 描述自定义的 helloJXK 标签 -->
  <tag>
  
  <!-- 标签名字:在jsp 中使用的标签的名字 -->
   <name>hello</name>
   
   <!-- 标签所在的全类名 -->
   <tag-class>athome.simpletag.SimpleTag</tag-class>
   
   <!-- 标签类型 -->
   <body-content>empty</body-content>
   
 <!-- 参数 -->   
   <attribute>
   
    <!-- 参数名 -->
    <name>value</name>
    
    <!-- 参数是否必须 -->
    <required>true</required>
    
    <!-- 参数是否可以接受运行时表达式的值 -->
    <rtexprvalue>true</rtexprvalue>
    
   </attribute>
   <attribute>
   
    <name>count</name>
    
    <required>false</required>
    
    <rtexprvalue>false</rtexprvalue>
    
   </attribute>
  </tag>
<taglib>

在 jsp 中

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入标签库 -->
<%@ taglib prefix="athome" uri="http://www.athome.com/myTag/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <athome:hello value="athome" count="10"/>
</body>
</html>
2. 实现标签 -athome:Max num1=" p a r a m . a " n u m 2 = " {param.a }" num2=" param.a"num2="{param.b }- (的都两个参数的最大值)

java 中

public class MaxTag extends SimpleTagSupport {
 private String num1;
 private String num2;
 public void setNum1(String num1) {
  this.num1 = num1;
 }
 public void setNum2(String num2) {
  this.num2 = num2;
 }
 @Override
 public void doTag() throws JspException, IOException {
  //得到 pageContext
  PageContext pageContext = (PageContext) getJspContext();
  //得到两个参数的值
  int a = Integer.parseInt(num1);
  int b = Integer.parseInt(num2);
  //得到 out 隐含变量
  JspWriter out = pageContext.getOut();
  //打印
  out.println(a > b ? a : b);
 }
}

tld 中(这儿只有说明的部分,全部内容参考上一个例子,下同)

 <!-- 得到最大值 -->
  <tag>
   <name>Max</name>
   <tag-class>athome.simpletag.MaxTag</tag-class>
   <body-content>empty</body-content>
   
   <attribute>
    <name>num1</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
   
   <attribute>
    <name>num2</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
   
  </tag>

jsp 中

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入标签库 -->
<%@ taglib prefix="athome" uri="http://www.athome.com/myTag/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <athome:Max num1="${param.a }" num2="${param.b }"/>
</body>
</html>
3.(athome:printUpper time=“10”>come on 😒{param.name }</athome:printUpper) ----实现将标签体大写并打印time 次

java中

public class printUpper extends SimpleTagSupport {
 private String time;
 public void setTime(String time) {
  this.time = time;
 }
 
 @Override
 public void doTag() throws JspException, IOException {
  //得到标签体
  JspFragment bodyContent = getJspBody();
  StringWriter sw = new StringWriter();
  bodyContent.invoke(sw);
  String content = sw.toString();
  
  //变为大写
  content = content.toUpperCase();
  int count = 1;
  
  //循环输出
  try {
   count = Integer.parseInt(time);
  } catch (Exception e) {}
  
  for (int i = 0; i < count; i++) {
   getJspContext().getOut().println((i+1) + "," + content);
   getJspContext().getOut().println("<br>");  }
 }
}

tld 文件中:

<tag>
   <name>printUpper</name>
   <tag-class>athome.simpletag.printUpper</tag-class>
   <body-content>scriptless</body-content>
   
   <attribute>
    <name>time</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
  </tag>

jsp 文件中(引用同上,省略,下同)

<athome:printUpper time="10">come on :${param.name }</athome:printUpper>
5模拟实现 foreach

java中

public class ForEachDemo extends SimpleTagSupport {
 private Collection<?> items;
 private String val;
 
 public void setItems(Collection<?> collection) {
  this.items = collection;
 }
 
 public void setVal(String val) {
  this.val = val;
 }
 
 @Override
 public void doTag() throws JspException, IOException {
 
  // 遍历 collection 
  if (items != null) {
   for (Object object : items) {
   
    //将遍历到的对象放在 pageContext 中 ,键:var,值是遍历的对象
    getJspContext().setAttribute(val, object);
    
    //将标签内容直接输出到页面上
    getJspBody().invoke(null);
   }
  }
 }
}

tld中:

<tag>
   <name>forEach</name>
   <tag-class>athome.simpletag.ForEachDemo</tag-class>
   <body-content>scriptless</body-content>
   
   <attribute>
    <name>items</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
   
    <attribute>
    <name>val</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
  </tag>

jsp 中

<body>
 <%
  ArrayList<Customer> customers = new ArrayList<>();
  customers.add(new Customer(1,"AAA",10));
  customers.add(new Customer(2,"BBB",11));
  customers.add(new Customer(3,"CCC",12));
  customers.add(new Customer(4,"DDD",13));
  customers.add(new Customer(5,"EEE",14));
  
  request.setAttribute("customers", customers);
 %>
 <athome:forEach items="${requestScope.customers }" val="customer">
  ${customer.id }--${customer.name }--${customer.age}<br>
 </athome:forEach>
 
 </body>
6.父标签中有子标签的情况

例如:jstl 中的 c:choose

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 <c:choose>
  <c:when test="${param.age > 24 }">大学毕业</c:when>
  <c:when test="${param.age > 20 }">高中毕业</c:when>
  <c:otherwise>高中以下学历</c:otherwise>
 </c:choose>

模拟实现:
java中
choose Java类:

public class ChooseTag extends SimpleTagSupport {

 private boolean flag = true;
 
 public boolean isFlag() {
  return flag;
 }
 
 public void setFlag(boolean flag) {
  this.flag = flag;
 }
 
 @Override
 public void doTag() throws JspException, IOException {
  getJspBody().invoke(null );
 }
}

when 类:

public class WhenTag extends SimpleTagSupport {
 private boolean test;
 public void setTest(boolean test) {
  this.test = test;
 }
 
 @Override
 public void doTag() throws JspException, IOException {
 
  //若 test 且 parentFlag 都是真
  if (test) {
  
   //得到父标签
   JspTag parent = getParent();
   ChooseTag parentTag = (ChooseTag) parent;
   
   //得到父节点的 flag
   boolean parentFlag = parentTag.isFlag();
   if (parentFlag) {
    getJspBody().invoke(null);
    parentTag.setFlag(false);
   }
  }
 }
}

OtherWise类

public class OtherWise extends SimpleTagSupport {

  @Override
  public void doTag() throws JspException, IOException {
  
   //得到父标签
   ChooseTag parent = (ChooseTag) getParent();
   if (parent.isFlag()) {
    getJspBody().invoke(null);
   }
  }
}

tld文件中

<!-- 模拟选择标签 -->
  <tag>
   <name>Choose</name>
   <tag-class>athome.simpletag.ChooseTag</tag-class>
   <body-content>scriptless</body-content>
</tag>

<tag>
   <name>When</name>
   <tag-class>athome.simpletag.WhenTag</tag-class>
   <body-content>scriptless</body-content>   
   
    <attribute>
    <name>test</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
   </attribute>
   
</tag>

   <tag>
   <name>OtherWise</name>
   <tag-class>athome.simpletag.OtherWise</tag-class>
   <body-content>scriptless</body-content>
</tag> 

jsp 中:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="athome" uri="http://www.athome.com/myTag/core"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <!-- 模拟的标签 -->
 <athome:Choose>
  <athome:When test="${param.age > 24 }">大学毕业</athome:When>
  <athome:When test="${param.age > 20 }">高中毕业</athome:When>
  <athome:OtherWise>高中以下学历</athome:OtherWise>
 </athome:Choose>

<!-- jstl 中的 -->
 <c:choose>
  <c:when test="${param.age > 24 }">大学毕业</c:when>
  <c:when test="${param.age > 20 }">高中毕业</c:when>
  <c:otherwise>高中以下学历</c:otherwise>
 </c:choose>
 <br><br>
</body>
</html>



补充

在这里插入图片描述

这儿不能是脚本
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值