写点什么

JSP 标签

  • 2022 年 5 月 14 日
  • 本文字数:5001 字

    阅读完需:约 16 分钟

③、doStartTag 方法内返回值 EVAL_BODY_INCLUDE——跳到 doAfterBody 方法,内返回值 EVAL_BODY_AGAIN(会多次执行此处)——直到 doAfterBody,返回值为 eval_page——最后执行 doEndTag


四、论证这三条路线的执行顺序


1、第一条路线:Demo.java:呈现结果:打印出"Demo-doStartTag 进去了"与"Demo-doEndTag 进去了", 论证了第一条的正确性


package com.lv;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class Demo extends BodyTagSupport{



?? ?@Override


?? ?public int doStartTag() throws JspException {


?? ??? ?System.out.println("Demo-doStartTag 进去了");


//?? ??? ?return super.doStartTag();


?? ??? ?return SKIP_BODY;


?? ?}


?? ?


?? ?@Override


?? ?public int doAfterBody() throws JspException {


?? ??? ?// TODO Auto-generated method stub


?? ??? ?return super.doAfterBody();


?? ?}


?? ?


?? ?@Override


?? ?public int doEndTag() throws JspException {


?? ??? ?System.out.println("Demo-doEndTag 进去了");


?? ??? ?return super.doEndTag();


?? ?}



}


?


输出结果:



2、第二条路线:能打印出三条内容:"Demo2-doStartTag 进去了","Demo2-doAfterBody 进去了"


与"Demo2-doEndTag 进去了",论证了第二条路线的正确性。


package com.lv;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class Demo2 extends BodyTagSupport{


?? ?@Override


?? ?public int doStartTag() throws JspException {


?? ??? ?System.out.println("Demo2-doStartTag 进去了");


//?? ??? ?return super.doStartTag();


?? ??? ?return EVAL_BODY_INCLUDE;


?? ?}


?? ?


?? ?@Override


?? ?public int doAfterBody() throws JspException {


?? ??? ?System.out.println("Demo2-doAfterBody 进去了");


?? ??? ?return EVAL_PAGE;


?? ?}


?? ?


?? ?@Override


?? ?public int doEndTag() throws JspException {


?? ??? ?System.out.println("Demo2-doEndTag 进去了");


?? ??? ?return super.doEndTag();


?? ?}



}


?



3.第三条路线:结果会执行出"Demo3-doStartTag 进去了","Demo3-doAfterBody 进去了"执行多遍,


最后执行"Demo3-doEndTag 进去了",结论正确。


package com.lv;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class Demo3 extends BodyTagSupport{



?? ?@Override


?? ?public int doStartTag() throws JspException {


?? ??? ?System.out.println("Demo3-doStartTag 进去了");


//?? ??? ?return super.doStartTag();


?? ??? ?return EVAL_BODY_INCLUDE;


?? ?}


?? ?


?? ?@Override


?? ?public int doAfterBody() throws JspException {


?? ??? ?System.out.println("Demo3-doAfterBody 进去了");


?? ??? ?return EVAL_BODY_AGAIN;


?? ?}


?? ?


?? ?@Override


?? ?public int doEndTag() throws JspException {


?? ??? ?System.out.println("Demo3-doEndTag 进去了");


?? ??? ?return super.doEndTag();


?? ?}



}


?



五、案例


1、自定义 if 标签(开发一个控制标签)


案例:第一与第二条路线的实际应用


c:if test=true 是要输出标签体的 ?要输出就走第二条路线


c:if test=false 是不输出标签体的 不输出就走第一条路线


package com.lv;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class IfTag extends BodyTagSupport{


?? ?


?? ?private boolean test;


?? ?


?? ? public boolean isTest() {


?? ??? ?return test;


?? ?}


?? ?public void setTest(boolean test) {


?? ??? ?this.test = test;


?? ?}


?? ?@Override


?? ??? ?public int doStartTag() throws JspException {


//?? ?需要一个变量来控制返回值,从而控制本标签走第一条路线还是第二条路线


?? ??? ??? ?return test?EVAL_BODY_INCLUDE:SKIP_BODY;


?? ??? ?}


}


?


tid 文件


? <tag>


? ? <name>if</name>


? ? <tag-class>com.lv.IfTag</tag-class>


? ? <body-content>JSP</body-content>


? ? <attribute>




? ? ? ? <name>test</name>




? ? ? ? <required>true</required>




? ? ? ? <rtexprvalue>false</rtexprvalue>


? ? </attribute>


? </tag>


最终能够引用:



得到结果:



?


2、set 与 out 标签的开发(开发数据标签)


1. 第一条路线


只不过,set,out 标签本身是没有标签体的,需要在页面上输出内容,


需要借助一个类 JspWriter。


2.在没有标签体的情况下,是通过 JspWriter 来输出内容的


SetTag:


package com.lv;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class SetTag extends BodyTagSupport{


?? ?


//?? ?存放标签的键


?? ?private String var;


//?? ?存放标签对应的值


?? ?private Object value;


?? ?public String getVar() {


?? ??? ?return var;


?? ?}


?? ?public void setVar(String var) {


?? ??? ?this.var = var;


?? ?}


?? ?public Object getValue() {


?? ??? ?return value;


?? ?}


?? ?public void setValue(String value) {


?? ??? ?this.value = value;


?? ?}


?? ?@Override


?? ??? ?public int doStartTag() throws JspException {


//?? ??? ?将 value 值保存到 var 对应的变量中


//?? ??? ?jsp 传递 name 给 var,转递张三给 value


//?? ??? ?那么需要把张三赋值给 name


?? ??? ?pageContext.setAttribute(var, value);


?? ??? ??? ?return super.doStartTag();


?? ??? ?}


}


?


OutTag:


package com.lv;



import java.io.IOException;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.JspWriter;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class OutTag extends BodyTagSupport{


?? ?


?? ?private Object value;



?? ?public Object getValue() {


?? ??? ?return value;


?? ?}



?? ?public void setValue(Object value) {


?? ??? ?this.value = value;


?? ?}


?? ?


?? ?@Override


?? ?public int doStartTag() throws JspException {


?? ??? ?JspWriter out = pageContext.getOut();


?? ??? ?try {


?? ??? ??? ?out.print(value);


?? ??? ?} catch (IOException e) {


?? ??? ??? ?// TODO Auto-generated catch block


?? ??? ??? ?e.printStackTrace();


?? ??? ?}


?? ??? ?return super.doStartTag();


?? ?}


}


?


tid 文件:


?<tag>


? ? <name>set</name>


? ? <tag-class>com.lv.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>


??


? ?<tag>


? ? <name>out</name>


? ? <tag-class>com.lv.OutTag</tag-class>


? ? <body-content>JSP</body-content>


? ? <attribute>


? ? ? ? <name>value</name>


? ? ? ? <required>true</required>


? ? ? ? <rtexprvalue>true</rtexprvalue>


? ? </attribute>


? </tag>


最终调用:


<z:set var="name" value="张三"></z:set>


?? ??? ?<z:out value="${name }"></z:out>


输出结果:



《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】


3、foreach 标签开发


熟悉第二第三路线的开发流程


1、最少接受两个参数


2、一定会有标签体的,那么对应需要重写 doAfterBody 方法


3.必定有判断条件决定 doAfterBody 的返回值是 EVAL_PAGE 还是 EVAL_BODY_AGAIN


将取集合元素的过程,看成指针下移取值的过程,如果指针还能指向下一个,那么返回值为 EVAL_BODY_AGAIN


如果指针没有指下一个元素,那么返回值为 EVAL_PAGE


指针是迭代器里面的产物,所以需要将迭代器保存并提供到 doAfterBody 中使用


package com.lv;



import java.util.ArrayList;


import java.util.Iterator;


import java.util.List;



import javax.servlet.jsp.JspException;


import javax.servlet.jsp.tagext.BodyTagSupport;



public class ForeachTag extends BodyTagSupport{


?? ?


?? ?private String var;


?? ?private List<Object> items=new ArrayList<Object>();


?? ?


?? ?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 {


//?? ??? ?在此处保存迭代器,供 doAfterBody 中使用


?? ??? ?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()) {


//?? ??? ??? ?在页面上,需要通过 var 将集合中的对象拿到


?? ??? ??? ?pageContext.setAttribute(var, it.next());


//?? ??? ??? ?保存指针下移后的状态


?? ??? ??? ?pageContext.setAttribute("it", it);


//?? ??? ??? ?继续循环


?? ??? ??? ?return EVAL_BODY_AGAIN;


?? ??? ?}else {


//?? ??? ??? ?结束循环


?? ??? ?return EVAL_PAGE;


?? ??? ?}


?? ?}


}


?


tid 文件:


<tag>


? ? <name>foreach</name>


? ? <tag-class>com.lv.ForeachTag</tag-class>


? ? <body-content>JSP</body-content>


? ? <attribute>


? ? ? ? <name>var</name>


? ? ? ? <required>true</required>


? ? ? ? <rtexprvalue>false</rtexprvalue>


? ? </attribute>


? ? ?<attribute>


? ? ? ? <name>items</name>


? ? ? ? <required>true</required>


? ? ? ? <rtexprvalue>true</rtexprvalue>


? ? </attribute>


? </tag>


添加数据,foreach 遍历:


<%


?? ??? ?List user=new ArrayList<>();


?? ??? ?user.add(new User("u001","zs",24));


?? ??? ?user.add(new User("u002","ls",23));


?? ??? ?user.add(new User("u003","ww",23));


?? ??? ?request.setAttribute("users", user);


?? ??? ?%>


?? ??? ?<z:foreach items="${user }" var="users">


?? ??? ?{users.name }


?? ??? ?</z:foreach>



4、select 标签的开发


分析:


1、数据源属性 items,用于遍历展示的(比如实体类 User 表中的 id 为 option 中的 value 值,name 为 option 中的文本 text)


2、对象 key 属性 textKey,用于 option 中的 value


3、对象 value 属性 textVal,用于对应 option 中的 text


4、对象默认的 key 属性 headerTextKey,用于对应默认的 option 中的 value


5、对象默认 value 属性 headerTextVal,用于对应默认的 option 中的 text


6、对象回显值属性 selectedVal,用于判断是否数据回显选中


没有标签体,有需要往页面输出内容 JspWriter


package com.lv;



import java.io.IOException;


import java.lang.reflect.Field;


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 com.sun.org.apache.xml.internal.serializer.ToHTMLSAXHandler;



public class SelectTag extends BodyTagSupport{


?? ?


?? ?private List<Object> items=new ArrayList<Object>();


?? ?private String textKey;//用于对应的 option 中的 value


?? ?private String textVal;//用于对应 option 中的 text


?? ?private String headerTextKey;//用于对应默认的 option 中的 value


?? ?private String headerTextVal;//用于对应默认的 option 中的 text


?? ?private String selectedVal;//用于判断是否数据回显选中


//?? ?定义属性美化,扩展/操作标签


?? ?private String cssStyle;//美化


?? ?private String id;//绑定事件。。。操作标签


?? ?private String className;//美化


?? ?


?? ?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;

用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
JSP标签_Java_爱好编程进阶_InfoQ写作社区