JSTL
- 核心标签库(core)---c(重点)
- XML(x:操作xml的标签库)
- SQL(sql标签库)
- FMT(fmt:国际化标签库)
- JSTL函数(EL函数)el
<c:out>标签
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| value | true | Object | 指定要输出的内容 |
| escapeXml | true | Boolean | 指定是否将>、<、&、'、" 等 特殊字符进行HTML编码转换 后再进行输出。默认值是true。 |
| default | true | Object | 指定假设value属性的值为null时所输出的默认值 |
<!-- c:out 输出数据到浏览器 -->
<c:out value="Hello c out "></c:out>
Hello c out
<!-- 输出一个变量 -->
<c:set var="m" value="10" scope="page"/>
<c:out value="${m}"></c:out>
${m }
<!-- 转义HTML 默认转义,通过设置escapeXml 为false 不进行转义-->
<c:out value="<a href='xxx'>link</a>" />
${fn:escapeXml("<a href='xxx'>link</a>") }
<!-- 同意输出默认值 ,假设city不存在,输出北京-->
<c:out value="${city}" default="北京"></c:out>
${empty city?"北京":city }
<c:set>标签
- 向4个域中存入值。(var value scope属性)
- 设置Web域中的java.util.Map 类型的属性对象或JavaBean类型的属性对象的属性(target property value属性)
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| value | true | Object | 用于指定属性 |
| var | false | String | 用于指定要设置的Web域属性的名称 |
| scope | false | String | 用于指定属性所在的Web域 |
| target | true | Object | 用于指定要设置属性的对象。这个对象必须是 JavaBean对象或java.util.Map对象 |
| property | true | String | 用于指定当前要为对象设置的属性名称 |
<c:remove>标签
request.setAttribute("age",20);
// 删除age
request.removeAttribute("age");
%>
<c:set var="age" value="20" scope="request"></c:set>
<c:remove var="age" scope="request"/>
<c:catch>标签
- <c:catch>标签用于捕获嵌套在标签中的内容抛出的异常。其语法格式例如以下:<c:catch [var="varName"]> nested actions </c:catch>
- var属性用于标识<c:catch>标签捕获的异常对象,它将保存在page这个web域中。
<%@ page contentType="text/html;charset=gb2312" %>
<c:catch var="myex“ >
<%
10/0;
%>
</c:catch>
异常:<c:out value="${myex}" /> ${myex}<br />
异常 myex.getMessage:<c:out value="${myex.message}" /><br />
异常 myex.getCause:<c:out value="${myex.cause}" /><br />
异常 myex.getStackTrace:<c:out value="${myex.stackTrace}" />
<c:if>标签
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| test | true | boolean | 决定是否处理标签体中的内容的条件表达式 |
| var | false | String | 用于指定将test属性的运行结果保存到某个Web域中的某个属性的名称 |
| scope | false | String | 指定将test属性的运行结果保存到哪个Web域中 |
<c:choose>
使用<c:choose>,<c:when>,<c:otherwise>三个标签,能够构造类似于"if-else if-else"的复杂条件推断结构
<%@ page contentType="text/html;charset=gb2312" %>
<c:set value="${param.count}" var="count“ /> pageContext(count,2)
<c:choose>
<c:when test="${count == 0}">
对不起,没有符合您要求的记录。
</c:when>
<c:otherwise>
符合您要求的记录共同拥有${count}条.
</c:otherwise>
</c:choose>
<c:forEach>标签
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| var | false | String | 指定将当前迭代到的元素保存到page这个域中的属性名称 |
| varStatus | false | String | 记住用于保存迭代信息的对象 |
| items | true | 不论什么支持的类型 | 将要迭代的集合对象 |
| begin | true | int | 假设指定items属性,就从集合中的第begin个元素開始进行迭代 。begin的索引值从0開始编号。假设没有指定items属性,就从 begin指定的值開始迭代。直到end值时结束迭代 |
| end | true | int | 与begin属性类似 |
| step | true | int | 指定迭代的步长,即迭代因子的迭代增量 |
<c:forEach>迭代数据
<c:forEach begin="1" end="10" step="1" var="i">
<c:set var="sum" value="${sum + i}" scope="page"></c:set>
</c:forEach>
${sum }
varStatus属性:
| 属性 | 类型 | 意义 |
| index | number | 如今指到成员的索引 |
| count | number | 总共指到成员的总数 |
| first | boolean | 如今指到的成员是否是第一个成员 |
| last | boolean | 如今指到的成员是否是最后一个成员 |
<c:if test="${status.count % 3 == 0}">
<font color="red">${i }</font>
</c:if>
<c:if test="${status.count % 3 != 0}">
<font color="blue">${i }</font>
</c:if>
</c:forEach>
在WebRoot/jstl文件夹下新建forEach.jsp
<c:forTokens>
| 名称 | 说明 | EL | 类型 | 必须 | 默认值 |
| var | 用来存放如今指到的成员 | N | String | 否 | 无 |
| items | 被迭代的字符串 | Y | String | 是 | 无 |
| delims | 定义用来切割字符串的字符 | N | String | 是 | 无 |
| varStatus | 用来存放如今指到的相关成员信息 | N | String | 否 | 无 |
| begin | 開始的位置 | Y | int | 否 | 0 |
| end | 结束的位置 | Y | int | 否 | 最后一个成员 |
<c:forTokens items="${s}" delims="," var="e">
${e }
</c:forTokens>
items=要切分的字符串
delims=按着什么格式切分
var=定义变量
[varStatus="varStatusName"]
[begin="begin"]
[end="end"]
[step="step"]>
//body内容
</c:forTokens>
<c:param>标签
- 在JSP页面进行URL的相关操作时。常常要在URL地址后面附加一些參数。<c:param>标签能够嵌套在<c:import>、<c:url>或<c:redirect>标签内,为这些标签所使用的URL地址附加參数。
- <c:param>标签在为一个URL地址附加參数时。将自己主动对參数值进行URL编码,比如:假设传的參数值为“中国”。则将其转换为“%d6%d0%b9%fa”后再附加到URL地址后面,这也就是使用<c:param>标签的最大优点
- 演示样例:<c:param name="name" value="value" />
<c:import>标签
| 名称 | 说明 | EL | 类型 | 必须 | 默认值 |
| url | 一文件被包括的地址 | Y | String | 是 | 无 |
| context | 项目虚拟路径 | Y | String | 否 | 无 |
| var | 储存被包括的文件的内容(以String类型存入) | Y | String | 否 | 无 |
| scope | var变量的JSP范围 | N | String | 否 | page |
| charEncoding | 被包括文件的内容的编码方式 | Y | String | 否 | 无 |
| varReader | 储存被包括的文件的内容(以Reader类型存入) | N | String | 否 | 无 |
<c:import url="/jstl/foreach.jsp" context="/day8"></c:import>
<hr/>
<!-- 引入不显示,将内容保存还有一个变量中 -->
<c:import url="/jstl/foreach.jsp" context="/day8" var="content" scope="page"></c:import>
${content }
<c:import url="http://java.sun.com" >
<c:param name="test" value="1234" />
</c:import>
<c:url>标签
(类似于Session追踪 尤其是当浏览器禁用cookie后,就是说实现了session追踪的功能)
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| value | true | String | 指定要构造的URL |
| var | false | String | 指定将构造出的URL结果保存到Web域中的属性名称 |
| scope | false | String | 指定将构造出的URL结果保存在哪个域中 |
改动choose.jsp 例如以下:
禁用浏览器的cookie后。执行例如以下:
点击choose跳转到choose.jsp
<c:redirect>标签
| 属性名 | 是否支持EL | 属性类型 | 属性描写叙述 |
| url | true | String | 指定要转发或重定向到的目标资源的URL地址 |
| context | true | String | 当要使用相对路径重定向到同一个server下的其它WEB应用程序中的 资源时,context属性指定其它WEB应用程序的名称 |
// 曾经重定向
// response.sendRedirect("/day12/index.jsp");
%>
<c:redirect url="/index.jsp" context="/day12"></c:redirect>
EL函数库
JSTL中的经常使用EL函数
fn:toLowerCase
fn:toUpperCase
fn:trim
fn:length
fn:split
fn:join
fn:indexOf
fn:indexOf函数接收两个字符串类型的參数。假设第一个參数字符串中包括第二个參数字符串,那么无论第二个參数字符串在第一个參数字符串中出现几次。fn:indexOf函数总是返回第一次出现的索引值;假设第一个參数中不包括第二个參数。则fn:indexOf函数返回-1。假设第二个參数为空字符串,则fn:indexOf函数总是返回0。
fn:contains
fn:contains函数在比較两个字符串是否相等时是大写和小写敏感的。
fn:startsWith
假设第二个參数为空字符串。则fn:startsWith函数总是返回true。比如:
fn:replace
fn:substring
fn:substring函数接收三个參数,第一个參数是用于指定要操作的源字符串。第二个參数是用于指定截取子字符串開始的索引值,第三个參数是用于指定截取子字符串结束的索引值,第二个參数和第三个參数都是int类型,其值都从0開始比如:
fn:substringAfter
自己定义EL函数开发步骤
开发EL function注意事项
package cn.itcast.el;
public class ElDemo1 {
public static String sayHello(String name){
return "hello "+name;
}
}
在WebRoot/WEB-INF下新建myfn的tld文件 并进行配置:在WebRoot根文件夹下新建el文件夹,在里面新建demo.jsp
自己定义标签
自己定义标签简单介绍
自己定义标签主要用于移除JSP页面中的Java代码。提高代码的复用性使用自己定义标签移除jsp页面在奇偶那个的Java代码。仅仅须要完毕下面步骤:
- 编写一个实现Tag接口的Java类(标签处理器)
- 编写标签库描写叙述符(tld)文件,在tld文件里对标签处理器类描写叙述成一个标签
- 參考Tomcat中example项目中的JSP部分
由于企业业务需求是多种多样的。所以常见开源框架仅仅能提供通用的Java代码功能。假设实现既定业务逻辑功能,须要自己定义标签。通过自己定义标签(简化复杂业务开发)简单标签
实现SimpleTag接口的标签通常称为简单标签。
- setJspContext方法:用于把JSP页面的pageContext对象传递给标签处理器对象。
- setParent方法:用于把父标签处理器对象传递给当前标签处理器对象。
- getParent方法:用于获得当前标签的父标签处理对象。
- setJspBody方法:用于把代表标签体的JspFragment对象传递给标签处理器对象。即传入标签体缓存对象(封装了标签体内容)
- doTag方法:用于完后全部标签逻辑,包含输出、迭代、改动标签体内容等。
在doTag方法中能够抛出javax.servlet.jsp.SkipPageException异常。用于通知WEB容器不再运行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。
SimpleTag接口方法的运行顺序:
- WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
- WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,仅仅有在标签存在父标签的情况下。WEB容器才会调用这种方法。
- 假设调用标签时设置了属性,容器将调用每一个属性相应的setter方法把属性值传递给标签处理器对象。
假设标签的属性值是EL表达式。则WEB容器首先计算表达式的值。然后把值传递给标签处理器对象。
- 假设简单标签有标签体。容器将调用setJSPBody方法把代表标签体的JspFragment对象传递进来。
- 容器调用标签处理器的doTag() 方法,开发者在方法内通过操作JspFragment对象。就能够实现是否运行、迭代、改动标签体的目的。
JSPFragment类
invoke方法具体解释
比如:
- 在标签处理器中假设没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容。
- 在标签体处理器中反复调用JspFragment.invoke方法。则标签体内容会被反复运行;
- 若想在标签处理器中改动标签体内容。仅仅需在调用invoke方法时指定一个可取出结果数据的输出流对象(比如:StringWriter)。让标签体的运行结果输出到该输出流对象中。然后从该输出流对象中取出数据进行改动后在输出到目标设备。就可以达到改动标签体的目的。
自己定义标签入门
自己定义带有标签体的标签
Body-content的配置
- empty:不能有标签体内容
- JSP:标签体内容能够是不论什么东西:EL、JSTL、<%= %>、<%%>,以及HTML;但不建议使用Java代码段,SimpleTag已经不再支持使用<body-content>JSP</body-content>
- scriptless:标签体内容不能是Java代码段,但能够是EL、JSTL等。
- tagdependent:标签体内容不做运算。由标签处理类自行处理,不管标签体内容是EL、JSP、JSTL,都不会做运算。
自己定义带有属性的标签
并提供set方法。页面的属性与类中的属性名称必须同样。
在TLD中描写叙述标签属性attribute
| 元素名 | 是否必须指定 | 描写叙述 |
| description | 否 | 用于指定属性的描写叙述信息 |
| name | 是 | 用于指定属性的名称。属性名称是大写和小写敏感的,而且不能以jsp、 _jsp、java和sun开头 |
| required | 否 | 用于指定在JSP页面中调用自己定义标签时是否必须设置这个属性。
其 |
| rtexprvalue | 否 | rtexprvalue是runtime expression value(执行时表达式)的英文简写, 用于指定属性值是一个静态值或动态值。其取值包含true和false,默认值 是false。false表示仅仅能为该属性指定静态文本值,比如"123"; true表示可 以为该属性指定一个JSP动态元素,动态元素的结果作为属性值。比如 JSP表达式<%=value %> |
| type | 否 | 用于指定属性值的Java类型。
默认是String |
标签的一个属性。自己定义标签所具有的每一个属性
都要相应一个<attribute>元素 。
<attribute>
<description>description</description>
<name>aaaa</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>ObjectType</type>
</attribute>
package cn.itcast.tag;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 对外输出Hello
* @author Administrator
*
*/
public class TagDemo1 extends SimpleTagSupport{
private PageContext pc;
public void doTag() throws JspException, IOException {
pc.getOut().write("Hello");
}
/**
* server默认先运行该方法
*/
public void setJspContext(JspContext pc) {
this.pc = (PageContext) pc;
}
}TagDemo2.java (有标签体 处理标签体内容)package cn.itcast.tag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 带有标签主体
* @author Administrator
*
*/
public class TagDemo2 extends SimpleTagSupport{
private PageContext pc;
public void doTag() throws JspException, IOException {
JspFragment jf = getJspBody();
StringWriter sw = new StringWriter();
//通过invoke方法将标签体内容写入到參数Writer对象sw中
jf.invoke(sw);
// 获取标签体内容
String content = sw.toString().toUpperCase();
pc.getOut().print(content);
}
public void setJspContext(JspContext pc) {
this.pc = (PageContext)pc;
}
}
TagDemo3.java (有属性 有标签体的自己定义标签)package cn.itcast.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 相似<c:if>标签,带有属性的
* @author Administrator
*
*/
public class TagDemo3 extends SimpleTagSupport{
private boolean test;
public void setTest(boolean test) {
this.test = test;
}
public void doTag() throws JspException, IOException {
if(test){
getJspBody().invoke(null);
}
}
}
在WebRoot/WEB-INF 文件夹下新建myc.tld文件
在WebRoot下新建tag目录。新建tag.jsp 測试自己定义标签内容
启动server。执行结果例如以下: