JSP自定义标签

最近在一个项目中,jsp页面的下拉框是通过从缓存到系统参数的数字字典中查找特定的标签属性类型,jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签。

自定义标签

下面我们先来开发一个自定义标签,然后再说它的原理吧!

 

自定义标签的开发步骤

 

步骤一

编写一个普通的java类,继承TagSupport~

 

复制代码
package com.vmaxtam.dotest;
import javax.servlet.jsp.tagext.TagSupport;

public class MyTagTest extends TagSupport {
    
}
复制代码

 

步骤二

重写父类的setPageContext方法,用于得到当前jsp页面的pageContext对象。

 

复制代码
public class MyTagTest extends TagSupport {    
    private PageContext pageContext;
    @Override
    public void setPageContext(PageContext pageContext) {
        this.pageContext=pageContext;
    }
}
复制代码

 

步骤三

重写父类的doStartTag方法,里面写上你定义的标签的java操作,这里我定义的标签用作向浏览器输出一大段信息:

 

复制代码
@Override
    public int doStartTag() throws JspException {
        
    try {
      pageContext.getResponse().getWriter().write("这是我写的一大段信息:ABCDEFGHIJKLMNOPQRSTUVWXYZ");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return super.doStartTag();
    }
复制代码

 

这样就完成一个标签处理程序了~别着急,写完程序我们还需要注册它。

 

步骤四

在你的web应用目录下,找到WEB-INF文件夹,在里面新建一个tld类型的文件

然后再里面注册你的标签吧:

复制代码
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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.0</tlib-version><!-- 代表标签库的版本号 -->
  <jsp-version>1.2</jsp-version><!-- 代表jsp的版本 -->
  <short-name>mtt</short-name><!-- 你的标签库的简称 -->
  <uri>http://vmaxtam.com/mytag</uri><!-- 你标签库的引用uri -->
  
  <tag>
      <name>mytah</name><!-- 你定义的标签的名称 -->
       <tag-class>com.vmaxtam.dotest.MyTagTest</tag-class><!-- 对应的标签处理程序:包名+类名 -->
      <body-content>JSP</body-content><!-- 标签体内容的格式 -->
  </tag>
 </taglib>
复制代码

如果你忘记了怎么写,可以参考jstl里的tld文件~

 

步骤五

你要在使用你定义的标签的jsp页面导入你的标签库!就像导入类包一样

只需在jsp页面写上下面内容:

 

<%@taglib uri="http://vmaxtam.com/mytag" prefix="mmt" %>

 

步骤6

以上5步已经把准备工作都做好了~下面我们来使用标签吧!

 

复制代码
<html>
  <head>   
    <title>My JSP 'testit.jsp' starting page</title>
  </head>
  
  <body>
      <mmt:mytag></mmt:mytag>
  </body>
</html>
复制代码

 

浏览器效果如下:

这样,我们就完成了一次自定义标签了,虽然我们知道步骤,但是不知道为什么这样就行,所以,下面来说一下它的原理:

 

自定义标签的原理

1)当服务器打开时,就会加载WEB-INF下的资源文件,包括web.xml 和 tld文件,把它们加载到内存

2)我们在浏览器输入http://localhost:8080/TestArea/testit.jsp来访问jsp页面

3)服务器读取testit.jsp里的内容,当读到

<%@taglib uri="http://vmaxtam.com/mytag" prefix="mmt" %> 

这一句的时候,就会在内存中找是否存在urihttp://vmaxtam.com/mytagtld文件,找不到就会报错

4)继续读取jsp页面,读到<mmt:mytag>这个标签的时候,就会通过uri找到tld文件,在tld文件中找到mytab是否被定义,是的话就得到它的tag-class的内容,然后去找到它对应的标签处理程序

5)实例化标签处理程序,利用生成的对象调用它里面的方法

这里服务器对标签处理程序里的方法也有一定的调用顺序      A)void setPageContext(PageContext pc)  --传入pageContext对象

B)void setParent(Tag t)              --如果有父标签,传入父标签对象,如果没有,则传入null

C)int doStartTag()                 --开始执行标签时调用。

D)int doEndTag()                --结束标签时调用

E)void release()                  --释放资源

 

如果你没有重写上面的方法,系统将会调用它的父类里的方法~

为什么会是这个顺序调用,是有证据的,下面我们来看看jsp被翻译为java源文件里的截取:

 

复制代码
private boolean _jspx_meth_itcast_005fshowIp_005f0(PageContext _jspx_page_context)
          throws Throwable {
    PageContext pageContext = _jspx_page_context;
    JspWriter out = _jspx_page_context.getOut();
    //  itcast:showIp
   1) 实例化ShowIpTag对象
    gz.itcast.tag.ShowIpTag _jspx_th_itcast_005fshowIp_005f0 = (gz.itcast.tag.ShowIpTag) _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.get(gz.itcast.tag.ShowIpTag.class);
    2)调用setPageContext方法
 _jspx_th_itcast_005fshowIp_005f0.setPageContext(_jspx_page_context);
    3)调用setParent方法
    _jspx_th_itcast_005fshowIp_005f0.setParent(null);
  4)调用doStartTag方法
    int _jspx_eval_itcast_005fshowIp_005f0 = _jspx_th_itcast_005fshowIp_005f0.doStartTag();
   5)调用doEndTag方法
    if (_jspx_th_itcast_005fshowIp_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
      _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.reuse(_jspx_th_itcast_005fshowIp_005f0);
      return true;
    }
    _005fjspx_005ftagPool_005fitcast_005fshowIp_005fnobody.reuse(_jspx_th_itcast_005fshowIp_005f0);
    return false;
  }
复制代码

自定义标签的属性

这个过程我们在简单标签内实现,以下是操作步骤

 

步骤一

在标签处理器类内声明一个成员变量,,这个成员变量就用来接受标签属性的值,然后再标签处理器类内为这个成员变量生成一个setter方法:

 

复制代码
public class MySimpleTag extends SimpleTagSupport {
    
    private Integer num;    
    
    public void setNum(Integer num) {
        this.num = num;
    }
复制代码

步骤二

要到tld文件注册这个属性,属性药注册在响应标签的<Tag>标签内

 

复制代码
  <tag>
      <name>simpletag</name>
      <tag-class>com.vmaxtam.dotest.MySimpleTag</tag-class>
      <body-content>scriptless</body-content>
      
      <attribute>
          <name>num</name> <!-- ??? -->
          <required>true</required><!-- ???????????????? -->
          <rtexprvalue>true</rtexprvalue><!-- ???????EL??? -->
      </attribute>
  </tag>
复制代码

rtexprvalue的全称是 Run-time Expression Value, 它用于表示是否可以使用JSP表达式.

当在<attribute>标签里指定<rtexprvalue>true</rtexprvalue>时, 表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定,



步骤三

这样就可以去使用属性了~

 

<body>
      <mmt:simpletag num="1001">我是标签里的内容</mmt:simpletag>我是标签后的内容
  </body>

 

上面的内容就可以创建一个基本功能的自定义标签了~


转载来源于:http://www.cnblogs.com/vmax-tam/p/4145334.html
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比和丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)和IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”和“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项和项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全和寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量和数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储和显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在 Android 开发中,Fragment 是界面的一个模块化组件,可用于在 Activity 中灵活地添加、删除或替换。将 ListView 集成到 Fragment 中,能够实现数据的动态加载与列表形式展示,对于构建复杂且交互丰富的界面非常有帮助。本文将详细介绍如何在 Fragment 中使用 ListView。 首先,需要在 Fragment 的布局文件中添加 ListView 的 XML 定义。一个基本的 ListView 元素代码如下: 接着,创建适配器来填充 ListView 的数据。通常会使用 BaseAdapter 的子类,如 ArrayAdapter 或自定义适配器。例如,创建一个简单的 MyListAdapter,继承自 ArrayAdapter,并在构造函数中传入数据集: 在 Fragment 的 onCreateView 或 onActivityCreated 方法中,实例化 ListView 和适配器,并将适配器设置到 ListView 上: 为了提升用户体验,可以为 ListView 设置点击事件监听器: 性能优化也是关键。设置 ListView 的 android:cacheColorHint 属性可提升滚动流畅度。在 getView 方法中复用 convertView,可减少视图创建,提升性能。对于复杂需求,如异步加载数据,可使用 LoaderManager 和 CursorLoader,这能更好地管理数据加载,避免内存泄漏,支持数据变更时自动刷新。 总结来说,Fragment 中的 ListView 使用涉及布局设计、适配器创建与定制、数据绑定及事件监听。掌握这些步骤,可构建功能强大的应用。实际开发中,还需优化 ListView 性能,确保应用流畅运
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值