jsp中提供了自定义标签技术,用于在jsp页面中提供简单的业务逻辑处理功能,可以避免在jsp页面中直接编写java代码造成的jsp页面难以维护和分工不清晰的问题
自定义标签是用户自定义的java页面元素,实质上是运行一个或者两个接口的JavaBean
1、创建标签处理器类:实际上通过标签调用的具体处理程序
//直接使用Tag接口编码繁琐,所以一般使用Sun提供的实现Tag接口的类,达到间接使用Tag接口的目的
//需求:接收2个整型参数,用于计算累加和
/*
<标签起始 属性=值>标签体标签结尾>*/
public class TestTag extends TagSupport {//标签属性值private int begin,end;// 处理器遇到标签起始时回调的方法public int doStartTag() throws JspException {//可以通过返回不同的常量值告知系统如何处理后续内容--标签体return EVAL_BODY_INCLUDE; //继续处理标签体// SKIP_BODY 跳过不处理标签体}// 遇到标签结束的回调处理方法public int doEndTag() throws JspException {//具体处理操作int res=0;for(int k=begin;k<=end;k++){res+=k;}//在页面上输出就和结果JspWriter out= pageContext.getOut();try {out.println(res);} catch (Exception e){throw new JspException(e); //交由jsp页面进行异常处理}//逻辑处理结束后通过返回值控制如何处理后续标签return SKIP_BODY;}@Override//释放资源public void release() {super.release();}public int getBegin() {return begin;}public void setBegin(int begin) {this.begin = begin;}public int getEnd() {return end;}public void setEnd(int end) {this.end = end;}
}
2、创建标签描述文件,用于针对标签名称和对应的处理类进行声明定义
标签库描述文件应该位于/WEB-INF/文件夹下,后缀必须为tld
1.0 yan /WEB-INF/yan.tld hello com.yan.tag.TestTag empty begin true end true
3、在页面中使用自定义标签库
<%@ taglib prefix="yan" uri="/WEB-INF/yan.tld" %>
标签库描述文件简称tld文件,实际上采用的是xml文件格式,用于定义用户的标签库
tld文中的元素主要可以分为3大类:标签库元素、标签元素和标签属性元素
用来设置标签库的相关信息
用来设置标签库默认的前缀名
用于设置标签库的唯一访问标识符,可以通过这个标识符唯一的指定特定的标签库
用于定义一个标签
用于设定对应的标签名称
用于设定对应的标签处理类。对应的处理类要求实现对应的标签接口
用于设定标签的主体内容。可以使用的属性值有三种:empty表示标签中没有标签体;JSP表示标签体可以加入jsp程序代码;tagdependent表示标签体的内容由标签自身进行处理
用于设置标签的属性,例如允许使用什么属性
用于设置属性名称
用于设置属性是否为必须的,默认值为false
用于设置属性值是否允许使用表达式,默认false使用自定义标签的目的在于不希望在jsp页面中出现java逻辑代码
1、当jsp引擎遇到自定义标签时,首先创建标签处理类的实例对象
2、调用setPageContext方法,将当前页面的PageContext对象传递给标签处理器类对象。有了PageContext则当前标签处理器对象则可以于jsp页面进行通信
3、setPageContext执行完毕后,则会调用setParent方法将当前标签的父标签对象传递给标签处理器对象。如果当前标签没有父标签,则传入null
4、当web容器执行到自定义标签的开始标记时,则自动调用doStartTag方法
5、当web容器指定到自定义标签的结束标记时,则自动调用 doEndTag方法
6、当web容器指定完自定义标签后,标签处理器对象会驻留在内存中,直到停止web应用时,web容器才会调用release方法执行资源回收
Sun为了规范自定义标签的使用,因为了标准标签库 JSTL,在JSTL中提供了一系列jsp标签,可以应用于jsp的应用开发过程。
JSTL标签库总供有5大类,核心标签c、国际化标签fmt,xml标签x,函数标签库fn。其中使用最多的是c标签库
核心标签库中总共有13个标签,例如out用于页面输出、set用于定义变量、remove用于移除指定对象,if用于条件判断等
在使用jstl标签库之前需要导入相应的jar包:jstl.jar和standard.jar
1、在maven的pom.xml中添加依赖
javax.servlet jstl 1.2
2、在页面中使用JSTL的核心标签库
1、在jsp页面中引入标签库。相关的标签库描述文件可以在jstl.jar的META-INF目录下查找到
c
http://java.sun.com/jsp/jstl/core <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>2、在可以中可以通过[prefix:标签名]的方式使用标签
${k}*${i}=${i*k}
EL表达式的支持在jsp2+已经纳入到jsp规范中,不需要JSTL的支持。主要用于在jsp页面中实现数据输出显示
在静态部分中可以使用${表达式}
的方式来获取并输出表达式的值
<%String ss="abc";request.setAttribute("ss",ss);
%>
${ss}
pageConext.findAttribute("key")
,如果小范围中没有查找到,则升级到大范围中继续查找,如果找到了则直接输出显示。如果在所有的范围中都没有查找到,不会显示null,而是显示为空串在指定范围中可以数据数据可以使用xxxScope的方式进行访问。例如pageScope、requestScope、sessionScope和applicationScope
<%String ss="abc";session.setAttribute("ss",new Date());request.setAttribute("ss",ss);
%>
${sessionScope.ss}
获取类对象中的属性【对象名.属性名】和【{对象名.属性名}】和【对象名.属性名】和【{对象名[‘属性名’]}】,但是需要注意的是实际上调用getXxx方法
<%pageContext.setAttribute("now",new Date());
%>
${now.year+1900}年${now.month+1}月${now.date}日
注意:当访问 null对象时,EL不会抛出空指针异常,仅仅就是不输出任何内容
使用EL直接访问集合
${数值名称[索引]}
。如果越界也不会抛出异常${List集合名称[索引值]}
。如果越界也不会抛出异常,但是无法访问Set集合${map['key']}
或者${map.key}
EL表达式中可以进行响应的计算操作,但是不支持字符串相加
算术运算符+、-、*、/ div、% mod
,不支持++、--
,除法获取的结果值为浮点型
关系运算符> gt、< lt 、>= ge、<= le、== eq、!= ne
逻辑运算符非! not、与&& and、或|| or
取值运算符方括号[]或者点.
三目运算符表达式1?表达式2:表达式3
empty运算符,判断变量为空:1、没有定义的变量;2、值为null的变量、3、值为""的空字符串。4、没有元素的数组或者集合
pageContext页面上下文,可以通过pageContext获取 jsp 页面中的其它默认对象,例如request、response、session等
4大范围page
param获取请求中的指定请求参数值,底层调用实际上是通过request.getParameter获取提交数据
paramValues获取请求中指定名称所对应的所有值,底层调用实际上是request.getParameterValues()获取
initPram获取当前应用的初始化参数,底层调用servletContext.getInitParameter
header用于获取请求头信息
headerValues获取请求头中指定属性的所有取值
cookie使用客户端跟踪用户的方法
使用EL表达式可以替换jsp中的输出表达式脚本,但是针对代码脚本并没有很好的解决方案
1、 不使用EL实现报错页面的输入框的数据回填
<%!
public String getParamValues(HttpServletRequest request,String key){String ss=request.getParameter("username");if(ss!=null && ss.trim().length()>0) return ss;return "";
}
%>
2、引入EL后可以直接使用
引入JSTL就是为了取代传统方法中在JSP页面中添加java程序的做法,以提高程序的可读性、维护性和便捷性,能够使jsp页面变得更加简洁
tld文件jstl.jar中的META-INF目录下c.tld
1、
用于输出数据,可以是字符串或者表达式,相当于脚本中的<% out.println()%>
或者<%= %>
<%
request.setAttribute("username","张三");
%>李四
//在页面上可以直接看到输出内容张三,实际上在html代码可以看到特殊符号已经转换为实体字符,例如空格对应的内容为 ,>对应的内容>李四 由于针对username对应的字符串内容按照原样输出,并不进行实体字符转换,所以在浏览器看到的是一个红色的 张三 这样的显示
2、
用于把一个对象存储到指定的域分为内或者将一个对象存储到Map或者javaBean中
注意:var和property不能同时存在、target和scope不能同时存在
针对JavaBean的操作
构建一个javabean对象
向javabean中的属性进行赋值----setXxx方法
输出 ${student} 或者使用
针对Map的操作
<%
Map map=new HashMap<>();
request.setAttribute("map",map); // 需要注意:在标签中使用或者通过EL访问的变量必须在4大范围中
%>
张三
${map}
将某个对象存储到指定的scope中
张三和李四
输出${sessionScope.username},相当于session.getAttribute("username")
3、
用于从指定的jsp范围中移除指定的变量,属性有2个var和scope。相当于调用removeAttribute操作
没有设置scope则默认值为page
小张
${student} 没有对应的输出
${empty(student.username) ? "已经被删除":"还是存在"} 判断student.username是否为空
4、
用于捕获抛出的异常
abcd
出现的异常对象为${eee}
5、
用于实现流程控制
123
${yyy mod 2}
${yyy}是偶数
${yyy}不是偶数
6、
组合使用,用于实现开关分支语句,相当于switch/case语句
其中没有表达式,只是表示开关分支结构的开始;
中test属性是一个条件判断,条件成立则执行标签体;
是所有
都不成立时执行的内容
<% String name="李四";
pageContext.setAttribute("name",name);%>
欢迎李四 欢迎王五 欢迎其它人
特殊情况下可以使用
结构实现if/else效果
<% request.setAttribute("sex",true); %>
男 女
7、
用于实现循环迭代操作
<%
List list=new ArrayList<>();
list.add("aaa");list.add("bbb");
list.add("ccc");list.add("ddd");
list.add("eee");list.add("fff");
request.setAttribute("list",list);
%>
${tt}
${tt}
${tt}---${ss.index}---${ss.count}---${ss.first}---${ss.last}
8、
用于将字符串以指定分割符进行分割,并迭代访问分割后的每一端内容
items参数只能是字符串,delims用于指定分割符
${ss}
9、
用于将其它静态或者动态文件包含到当前jsp页面中
${ss}
${err}
使用
正确的
与
的区别
只能包含同一个web应用中的文件,而
可以包含其它web应用中的文件,甚至是网络上的资源10、
主要用于进行URL相关操作时添加额外参数的,
可以嵌套在
、
或者
标签内,用于给这些标签的url地址上添加参数。这个标签添加参数时会自动对参数值进行URL编码
11、
用于在jsp页面中构建一个URL地址,主要目的实现URL重写
test.jsp?username=zhangsan
地址已经重写了
12、
用于实现请求的重定向操作,可以配合
在url地址中指定参数