web基础开发(六)

25 篇文章 0 订阅
19 篇文章 0 订阅

今天将开始jsp自定义标签的学习!!

自定义标签

为什么要使用自定义标签,一般我们是不予许在一个jsp页面呢或者html中有过多的java代码,这样会影响后期维护的效力。

定义自定义标签

  • 先建立自己的标签类,在类中实现自己的java代码。
  • 在web-inf目录下,建立后缀名为tld的文件,在其中进行自定义标签的注册。
具体代码如下:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class DateTag extends TagSupport{

	@Override
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss");
		
		try {
			pageContext.getOut().print(sdf.format(new Date()));//给个输出流
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return super.doStartTag();
	}
	

}

需要注意的是:自定义的标签类要继承TagSupport,并且实现dostarttag方法,在其中实现自己的java代码。

<?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">
    <tlib-version>1.1</tlib-version>
      <short-name>c1</short-name>
    <uri>/test-tag</uri>
      <tag>
        <name>date</name>       
          <tag-class>com.example.tag.DateTag</tag-class>
        <body-content>empty</body-content>
    </tag>
 </taglib>

注意点:
  1. 创建tld,不会出现上面那些配置信息,在使用的时候,最好从其他地方就行复制。
  2. 在上述复制结束之后,需要进行一些配置的修改。<uri>必须是/开始,后面的信息,你自己随便定义,,在jsp使用的时候,填写的uri必须一致。<tag>标签下的是标签库的描述类,<tag-classs>是配置标签类的位置。<name>是配置标签使用的名称,方便jsp中的使用。

使用自定义标签

<%@ taglib prefix="tag" uri="/test-tag" %>
 <tag:date/>

prefix是标签的前缀,可以自定义。必须引入和tld一致的uri,才能使用标签。使用标签的时候要对应寻找在tld文件配置的tag的name。

 如何控制标签体内容的执行

还是正常写一个标签,在标签的dostarttag方法中,需要就行逻辑处理。

在配置的时候,<body-content>这个标签下,有4个属性值,其中empty表示这个标签下没有内容;scriptless表示这个标签体下可以有 文本,el 表达式,jsp动作;jsp表示这个标签体下,可以出现jsp的脚本,就是java代码; tagdependent表示 标签的内容写入body-content,由自定义的标签体类处理,而不被jsp容器去解析。

具体代码如下:
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		String name = pageContext.getRequest().getParameter("name");//获取请求参数的值
		
		if(name!=null&&name.equals("laoqiang")){
			return EVAL_BODY_INCLUDE;//这个常量是执行标签体内容
			
		}else{
			return SKIP_BODY;//这个常量是跳过标签体内容
		

   <tag:ControlSkilTagContent>//携带内容的标签体
   sdasdadddddddd
   </tag:ControlSkilTagContent>

http://localhost:8080/TagTest/MyJsp.jsp?name=laoqiang
//请求网址

该代码可以实现类似,不同的用户,展示不同部分的页面。

如何实现标签结束控制

主要用途:判断用户是否从超链接和表单提交到本站点。

主要实现方法:
	@Override
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		String refer = request.getHeader("referer");//通过获取请求头的,来判断用户是从哪个地方连接过来,只有超练接和浏览器表单提交才可以。
		String url = "http://"+request.getServerName(); //获取本站点的url。
		System.out.println(url+"ggggggggggggg");
		if(refer!=null&&refer.startsWith(url)){
			return EVAL_PAGE;
		}else{
			try {
				pageContext.getOut().print("不能访问");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return SKIP_PAGE;
		}
		
	}

注意在本标签使用的时候,为了阻止该页面的显示,标签一定要放在前面。

自定义标签属性

主要实现的方法就是通过在标签类中定义所需要的属性的set、get方法。在配置标签的时候,通过attribute进行配置。具体代码例子如下:

public class DbConnectionTag extends TagSupport {
	private String driver;
	private String passward;
	private String username;
	private String url;
	private String sql;
	
	
	public String getSql() {
		return sql;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

	public String getDriver() {
		return driver;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public String getPassward() {
		return passward;
	}

	public void setPassward(String passward) {
		this.passward = passward;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	@Override
	public int doEndTag() throws JspException {
		 Connection conn = null;
		 Statement stat = null;
		 ResultSet res = null;
		// TODO Auto-generated method stub
	    try {
			Class.forName(this.driver);
		conn = 	DriverManager.getConnection(this.url, this.username, this.passward);
		stat = conn.createStatement();
		res = stat.executeQuery(this.sql);
		if(res!=null){
		while(res.next()){
			pageContext.getOut().println((res.getString("userNo")));
		}
		}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(res!=null){
				try {
					res.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(stat!=null){
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(conn!=null){
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	    
		return super.doEndTag();
	}

}

标签配置

  <tag>
        <name>DbConnectionTag</name>       
          <tag-class>com.example.tag.DbConnectionTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
        <name>driver</name>
        <required>true</required>
        </attribute>
        <attribute>
        <name>passward</name>//属性的名称
        <required>true</required>//属性是否必须显示使用
         <rtexprvalue>true</rtexprvalue>//这个标签是属性值可以是表达式
        </attribute>
        <attribute>
        <name>username</name>
        <required>true</required>
        </attribute>
        <attribute>
        <name>url</name>
        <required>true</required>
        </attribute>
        <attribute>
        <name>sql</name>
        <required>true</required>
        </attribute>
    </tag>

自定义标签的遍历

主要是通过doAfterBody方法来实现的,下面不多说,直接上代码:
public class IterationTag extends TagSupport {
	private String[] array;
	private int i = 1;
	private String var;
	
	
	public String getVar() {
		return var;
	}
	public void setVar(String var) {
		this.var = var;
	}
	public String[] getArray() {
		return array;
	}
	public void setArray(String[] array) {
		this.array = array;
	}
	@Override
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		if(array!=null&&array.length>0){
			pageContext.setAttribute(this.var, array[0]);
			return EVAL_BODY_INCLUDE;
		}else{
			return SKIP_BODY;
		}
		
	}
	@Override
	public int doAfterBody() throws JspException {
		// TODO Auto-generated method stub
		if(i<array.length){
			pageContext.setAttribute(this.var,array[i]);
			i++;
			return EVAL_BODY_AGAIN;
		}else{
			return SKIP_BODY;
		}
	}

}

利用这种标签遍历,会受到tomcat的缓存影响,第一次遍历出来,刷新后只有第0个位置元素。

修改标签体的内容

主要是通过定义标签处理类来继承BodyTagSupport,通过bodycontennt来获取标签体的内容。
public class ModifyBodyTag extends BodyTagSupport{
	private BodyContent bodyContent;
	@Override
	public int doEndTag() throws JspException {
		// TODO Auto-generated method stub
		String  s =  bodyContent.getString();//获取标签体的内容
		String newcontent  ="我是修改后的内容";
		JspWriter js = bodyContent.gtEnclosingWriter();//获取输出流
		try {
			js.write(newcontent);//将修改后的内容输出到jsp
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return EVAL_PAGE;
	}
	@Override
	public void setBodyContent(BodyContent b) {
		// TODO Auto-generated method stub
		super.setBodyContent(b);
		bodyContent = b;
	}

}

重点啦!!!

通过上面的代码,我们已经初步对自定义标签有所了解,但是上述的自定义标签方法,在使用的时候还是不是太方面,所以引入simpletag、simpletagsupport,但是在实际开发中,我们还是主要使用标签库2.0的simpletagsupport。下面介绍simpletagsupport的方法:
  1. dotag 是核心方法,处理标签逻辑。
  2. setparent 将父标签处理器对象传递给标签处理器。
  3. getparent 获取当前标签的父标签。
  4. setjspcontext 方法将jsp页面的pagecontext对象传递给标签处理器对象。
  5. setjspbody 将代表当前标签体的jspfragment对象给标签处理器对象。
  6. getjspcontext 返回jsp页面pagecontext。
  7. getjspbody 返回标签体的内容。
使用2.0标签,在配置的时候 :

 <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">
 </taglib>

tld文件的版本必须是2.0。

将之前几个例子通过simpletagsupport实现,代码如下:


	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		// TODO Auto-generated method stub
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM--dd HH:mm:ss");
				JspWriter js = getJspContext().getOut();//通过获取jsp的上下文,然后拿到输出流
				js.write(sdf.format(new Date()));//将内容写入到jsp。
			
	}

public class ControlSkilTagContent extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		PageContext pageContext = (PageContext) getJspContext();//获取pagecontext
		String name = pageContext.getRequest().getParameter("name");
		if(name!=null&&name.equals("liujinxin")){
			getJspBody().invoke(null);//getJspBody()得到Jspfragment,将内容作为标签体内容显示出来
			
		}
	}

public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		PageContext pageContext = (PageContext) getJspContext();
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		String refer = request.getHeader("referer");//判断请求是否是从超链接
		if(refer==null){
			throw new SkipPageException();//跳过jsp页面,不显示。
		}
	}

	private String[] array;
	private String var;
	
	
	public String getVar() {
		return var;
	}
	public void setVar(String var) {
		this.var = var;
	}
	public String[] getArray() {
		return array;
	}
	public void setArray(String[] array) {
		this.array = array;
	}

	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		PageContext pageContext = (PageContext) getJspContext();
		if(array!=null&&array.length>0){
			pageContext.setAttribute(this.var, array[0]);
			getJspBody().invoke(null);//将遍历出来的内容,作为标签体的内容输出出来。
		}
		
	}

	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		StringWriter sw = new StringWriter();//构建一个缓冲区.
		JspFragment jf = getJspBody();//获取标签体的内容
		jf.invoke(sw);//将标签体写到缓冲区中
		String content = sw.toString();//从缓冲区得到内容
		getJspContext().getOut().write(content);//将内容写到jsp页面上
	}

复合标签组合

  <tag:choose>
    <tag:when grade="$(grade)==100">
    very good 
    </tag:when>
    <tag:otherwise>
    加油吧,骚年!!!!!!!
    </tag:otherwise>
    </tag:choose>

主要代码如下

private boolean grade;
	
	public boolean isGrade() {
		return grade;
	}

	public void setGrade(boolean grade) {
		this.grade = grade;
	}

	@Override
	public void doTag() throws JspException, IOException {
		// TODO Auto-generated method stub
		super.doTag();
		if(grade){
			getJspBody().invoke(null);
			ChooseTag ct  = (ChooseTag)getParent();//获取该标签的父类标签
			ct.setFlag(true);//设置标志位
		}
	}

小伙伴们,jsp自定义标签已经学习完毕啦!





































































































































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值