JSP的标签技术
Posted 吴二喵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSP的标签技术相关的知识,希望对你有一定的参考价值。
jsp的标签技术:在jsp页面中最好不要出现java代码,这时我们可以使用标签技术将java代码替换成标签来表示。JSP的标签技术主要有下面四种:
- jsp标签。
- EL表达式。
- JSTL标签库。
- 自定义标签技术。
一、jsp标签
sun原生提供的标签,可以直接在jsp页面中使用。这种标签技术在实际使用中用的不是很多。它有很多标签,下面介绍其中的几种标签:
1、标签
标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:
<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
与include指令的比较:
标签是动态引入, 标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。 而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。不管是标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的html全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。
2、标签
标签用于把请求转发给另外一个资源。
语法:
<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
3、标签
当使用和标签引入或将请求转发给其它资源时,可以使用标签向这个资源传递参数。
语法1:
<jsp:include page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
语法2:
<jsp:forward page="relativeURL | <%=expression%>">
<jsp:param name="parameterName" value="parameterValue|<%= expression %>" />
</jsp:include>
标签的name属性用于指定参数名,value属性用于指定参数值。在和标签中可以使用多个标签来传递多个参数。
二、EL表达式
EL 全名为Expression Language。EL表达式最初出现的目的是为了取代jsp页面中的jsp脚本表达式,但是随着el的发展el的功能已经不限于此了。
EL表达式是JSP 2.0(JavaEE1.4)规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
注意:如果有些Tomcat服务器不能使用EL表达式,可以采取的方法是:
(1)升级成tomcat6
(2)在JSP中加入<%@ page isELIgnored=”false” %>
EL表达式主要有下面四种功能:获取数据、执行运算、获取常用开发对象和调用java方法。
1、获取数据
使用中括号的地方通常都可以使用点号替代,有两种情况除外:中括号中是数字或者中括号中包含特殊字符(-.)的情况。
注意:在中括号中如果不用双引号引起来则是变量,先找变量的值再拿变量的值使用。如果用双引号则是常量,直接使用常量的值。它只能获取数据,不要试图通过EL表达式来设置数据。
(1) 获取常量
字符串/数字/布尔类型,直接写在el表达式中,el直接进行输出。
(2) 获取域中的变量
如果el中写的是一个变量的名,则el会调用pageContext的findAttribute方法。在四大作用域中以给定的名字找对应的属性值,找到后进行输出,如果四个域中都找不到,什么都不输出。
(3) 获取数组中的数据
(4) 获取集合中的数据
(5) 获取Map中的数据
(6) 获取javabean的属性
示例如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="com.itheima.domain.Person"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>获取javabean的属性</h1><hr>
<%
Person p = new Person();
p.setName("Lilei");
p.setAge(17);
pageContext.setAttribute("p",p);
%>
${p.name }${p.age } ${p.name }
<img src="${pageContext.request.contextPath }/1.jpg"/>
<h1>获取Map中的数据</h1><hr>
<%
Map<String,String> map = new HashMap();
map.put("name","张三");
map.put("age","17");
map.put("gender","男");
map.put("addr","中国");
pageContext.setAttribute("map",map);
pageContext.setAttribute("name","age");
%>
${map["name"] }${map["addr"] }
${map.gender }${map.age }
<h1>获取集合中的数据</h1><hr>
<%
List<String> list = new ArrayList<String>();
list.add("甄嬛");
list.add("安陵容");
list.add("华妃");
pageContext.setAttribute("list",list);
%>
${list[2] }
<h1>获取数组数据</h1><hr>
<%
String [] names = {"容嬷嬷","紫薇","金锁","小燕子"};
pageContext.setAttribute("names",names);
%>
${names[2]}
<h1>获取域中的变量数据</h1><hr>
<%
String name = "李四";
pageContext.setAttribute("name",name);
%>
${name }
<h1>获取常量数据</h1><hr>
${"阿萨德发射点发" } ${199 } ${true }
</body>
</html>
2、执行运算
EL中支持的运算类型:算术运算、逻辑运算、比较运算、三元运算符、empty运算符。
算术运算:如果有非数字参与算数运算,el表达式会试图将非数字转换为数字后参与运算。
empty运算符:判断一个对象是否为null或字符串是否为空字符串或集合内容是否为空或域中是否没有任何属性。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>empty 运算符 : </h1><hr>
<%
String str = "aaaa";
pageContext.setAttribute("str",str);
List list = new ArrayList();
list.add("");
pageContext.setAttribute("list",list);
%>
${empty str }
${empty list}
${empty pageScope }
<h1>三元运算</h1><hr>
${10>9? "yes" : "no" }
<h1>逻辑运算</h1><hr>
&& and
|| or
! not
${not (3>2 and 1<2 or 10>3) }
<h1>比较运算</h1><hr>
> gt
< lt
>= ge
<= le
!= ne
==eq
${1 eq 1 } ${3 ge 2 } ${5+3 lt 3 }
<h1>算术运算</h1><hr>
${1+1 }
${1-2 }
${1+"2" }
</body>
</html>
3、获取常用开发对象
EL中内置了11个内置对象,这些对象EL内置的,不需要提前定义就可以直接在EL中使用。
pageContext -- 有了它可以很方便的获取jsp页面中的9大隐式对象
pageScope -- page域中属性组成的Map
requestScope -- request域中属性组成的Map
sessionScope -- session域中属性组成的Map
applicationScope --application域中属性组成的Map
param -- 所有请求参数组成的Map<String,String>
paramValues -- 所有请求参数组成的Map<String,String[]>
header -- 所有请求头组成的Map<String,String>
headerValues -- 所有请求头组成的Map<String,String[]>
cookie -- 所有cookie信息组成的Map<String,Cookie>
initParam -- 所有web应用的初始化参数组成Map
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%
pageContext.setAttribute("name","wang");
request.setAttribute("name","li");
%>
${requestScope.name}
${param.name } ${paramValues.like[2] }${header["Accept-Language"] }
${cookie.JSESSIONID.name }${cookie.JSESSIONID.value }
${initParam.name2 }
</body>
</html>
4、调用java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。一般来说,EL自定义函数开发与应用包括以下三个步骤:
- 编写一个Java类的静态方法。
- 编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
- 在JSP页面中导入和使用自定义函数。
编写完标签库描述文件后,需要将它放置到
三、JSTL标签库
JavaServer Pages Standard Tag Library是由JCP(Java Community Process)指定的标准,是提供给 Java Web 开发人员的一个标准通用的标签函数库,和 EL 配合来取代传统直接在页面上嵌入 Java 程序(Scripting)的做法,以提高程序可读性、维护性和方便性。
JSTL标签库主要包括五类:
- 核心标签库 (core) — c
- 国际化标签 fmt
- 数据库标签 sql
- XML标签 xml
- JSTL函数(EL函数) el
1、核心标签库
(1) 标签
标签用于输出一段文本内容到pageContext对象当前保存的“out”对象中。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>HTML转义输出</h1><hr>
<a href="#">xxx</a>
<c:out value="<a href=‘#‘>xxx</a>" ></c:out>
${fn:escapeXml(‘<a href="#">xxx</a>‘) }
<h1>输出默认值</h1><hr>
<%
String addr = "西二旗";
//pageContext.setAttribute("addr",addr);
%>
<c:out value="${addr}" default="北京"></c:out>
${addr == null?"北京" : addr }
<h1>输出变量</h1><hr>
<%
String name = "无双";
pageContext.setAttribute("name",name);
%>
<c:out value="${name}"></c:out>
${name }
<h1>输出常量</h1><hr>
<c:out value="阿斯蒂芬"></c:out>
${"啦啦啦啦" }
</body>
</html>
(2) 标签
标签用于把某一个对象存在指定的域范围内,或者设置Web域中的java.util.Map类型的属性对象或JavaBean类型的属性对象的属性。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@page import="com.itheima.domain.Person"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>修改域中的JavaBean的属性的值</h1><hr>
<%
Person p = new Person();
pageContext.setAttribute("p",p);
%>
<c:set target="${p}" property="name" value="克林顿"></c:set>
${p.name }
<h1>设置或修改域中的Map的值</h1><hr>
<%
Map map = new HashMap();
pageContext.setAttribute("map",map);
%>
<c:set target="${map}" property="cellphone" value="10010"></c:set>
<c:set target="${map}" property="cellphone" value="10086"></c:set>
${map.cellphone }
<h1>设置或修改域中的属性值</h1><hr>
<c:set var="name" value="韦小宝"></c:set>
<c:set var="name" value="阿珂"></c:set>
${name }
</body>
</html>
(3) 标签
标签用于删除各种Web域中的属性。
其语法格式如下:
<c:remove var="varName"
[scope="{page|request|session|application}"] />
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%
pageContext.setAttribute("name","蓝精灵");
request.setAttribute("name","小丸子");
session.setAttribute("name","机器猫");
application.setAttribute("name","蜡笔小新");
%>
<c:remove var="name"/>
${name }
</body>
</html>
(4) 标签
标签用于捕获嵌套在标签体中的内容抛出的异常。
其语法格式如下:
<c:catch [var="varName"]>nested actions</c:catch>
var属性用于标识标签捕获的异常对象,它将保存在page这个Web域中。
示例:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ 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}" />
(5) 标签
标签可以构造简单的“if-then”结构的条件表达式,它没有实现else的功能,如果想要实现else只能重新写一遍判断。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<c:if test="${2>1}">
确实是这样的....
</c:if>
<c:if test="${2<=1}">
你确定吗?
</c:if>
</body>
</html>
(6) 标签
标签用于指定多个条件选择的组合边界,它必须与和标签一起使用。使用,和三个标签,可以构造类似 “if-else if-else” 的复杂条件判断结构。
示例:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ 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>
(7) 标签
标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1>实验:遍历10到100的偶数,如果数字所在的位置是3的倍数,显示成红色</h1><hr>
<c:forEach begin="10" end="100" step="2" var="i" varStatus="stat">
<c:if test="${stat.count % 3 == 0}">
<font color="red">
${i }
</font>
</c:if>
<c:if test="${stat.count % 3 != 0}">
<font color="blue">
${i }
</font>
</c:if>
</c:forEach>
<h1>循环执行指定的内容若干次</h1><hr>
<c:forEach begin="0" end="10" step="2" var="i" >
${i },
</c:forEach>
<h1>遍历Map中的数据</h1><hr>
<%
Map map = new LinkedHashMap();
map.put("name","曹操");
map.put("age","59");
map.put("wife","小乔");
map.put("gender","男");
pageContext.setAttribute("map",map);
%>
<c:forEach items="${map}" var="entry" >
${entry.key }:${entry.value }<br>
</c:forEach>
<h1>遍历集合中的数据</h1><hr>
<%
List list = new ArrayList();
list.add("美国");
list.add("中国");
list.add("俄罗斯");
list.add("印度");
list.add("巴西");
pageContext.setAttribute("list",list);
%>
<c:forEach items="${list}" var="c">
${c }<br>
</c:forEach>
<h1>遍历数组中的数据</h1><hr>
<%
String [] city = {"北京","上海","广州","铁岭","葫芦岛"};
pageContext.setAttribute("city",city);
%>
<c:forEach items="${city}" var="c">
${c }<br>
</c:forEach>
</body>
</html>
(8) 标签
用来浏览一字符串中所有的成员,其成员是由定义符号所分隔的。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<c:forTokens items="www.baidu.com" delims="." var="str">
${str }<br>
</c:forTokens>
</body>
</html>
(9) 标签
标签用于实现请求重定向。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<c:redirect url="/index.jsp" context="${pageContext.request.contextPath}">
<c:param name="name" value="zhang"></c:param>
</c:redirect>
</body>
</html>
(10) 标签
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
from xxxxx....
<c:import url="/index.jsp" var="p" scope="page"></c:import>
xxxx
yyyy
${p }
zzzz
</body>
</html>
(11) 标签
标签用于在JSP页面中构造一个URL地址,其主要目的是实现URL重写。URL重写就是将会话标识号以参数形式附加在URL地址后面 。
示例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<%
String url = response.encodeURL(request.getContextPath()+"/index.jsp");
%>
<a href="<%= url %>">hhhh</a>
<c:url value="/index.jsp" context="${pageContext.request.contextPath}" var="url" scope="page"></c:url>
<a href="${url }">xxx</a>
</body>
</html>
(12) 标签
在JSP页面进行URL的相关操作时,经常要在URL地址后面附加一些参数。标签可以嵌套在、或标签内,为这些标签所使用的URL地址附加参数。
标签在为一个URL地址附加参数时,将自动对参数值进行URL编码,例如,如果传递的参数值为“中国”,则将其转换为“%d6%d0%b9%fa”后再附加到URL地址后面,这也就是使用标签的最大好处。
示例:
<c:param name="name" value="value" />
四、自定义标签技术
自定义标签技术分为传统标签和简单标签两种。
1、传统标签
使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤:
- 编写一个实现Tag接口的Java类(标签处理器类)。
- 编写标签库描述符(tld)文件,在tld文件中对标签处理器类描述成一个标签。
- 在JSP页面中引入tld文件,就可以在jsp页面中使用自定义标签了。
Tag接口的执行流程
JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法。
1、public void setPageContext(PageContext pc), JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
2、public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
3、public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
4、public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。
5、public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。
doStartTag 和 doEndTag方法来分别处理发现开始标签和发现结束标签时的代码。在doStartTag可以通过返回值来控制标签体是否允许执行,在doEndTag方法里可以通过返回值控制标签之后的剩余页面是否允许执行。
传统标签的这种开发方式,需要我们分析发现开始标签和发现结束标签时都需要执行什么代码,还需要分析到底要返回什么样的标签体控制程序执行,相对来说相当的繁琐,因此有了下面的简单标签。
示例(利用传统标签显示IP地址):
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
public class ShowIpTag implements Tag {
private PageContext pc = null;
public int doEndTag() throws JspException {
//EVAL_PAGE -- 结束标签之后的剩余页面需要去执行
//SKIP_PAGE -- 结束标签之后的剩余页面不要去执行
return 0;
}
public int doStartTag() throws JspException {
try {
String ip = pc.getRequest().getRemoteAddr();
pc.getOut().write(ip);
} catch (IOException e) {
e.printStackTrace();
}
//Eval_Body_Include -- 开始标签之后的标签体需要执行
//Skip_Body -- 开始标签之后的标签体不需要执行
return 0;
}
public Tag getParent() {
return null;
}
public void release() {
}
public void setPageContext(PageContext pc) {
this.pc = pc;
}
public void setParent(Tag t) {
}
}
2、简单标签
由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:
- setJspContext方法
- setParent
- getParent方法
- setJspBody方法
- doTag方法
以上是关于JSP的标签技术的主要内容,如果未能解决你的问题,请参考以下文章