自定义标签:
1.为什么用自定义标签
第一,用自定义标签可以增加jsp文件的维护性能
第二,用于处理复杂的业务逻辑,并提高可重用性
2.工作原理:
第一,我们需要在tld文件中定义标签
第二,这些定义好的标签到底能做什么需要由标签处理器来负责,所以要创建一个标签处理器
第三,在一个jsp文件中使用自定义标签,需要先引入这个标签的标签库,并指定前缀名,然后直接使用
当我们执行jsp文件,会先调用引入命令,找到tld文件,然后去找tld文件中标签对应的标签处理器类,找到类后,进行一些方法的调用,这些方法有的是回调方法,jsp容器会调用这些方法
3.Tag接口生命周期
A.先调用setPageContext()方法:初始化方法,配置环境,如:session,request,response,autoflush等
B.调用setParent()方法:设置标签的上一级标签
C.设置属性,如果没有属性就不调用
D.调用doStartTag()方法,这个方法返回EVAL_BODY_INCLUDE和SKIP_BODY,返回EVAL_BODY_INCLUDE计算正文内容,返回SKIP_BODY不计算body
E.调用doEndTag方法,EVAL_PAGE或者SKIP_PAGE,当返回值为EVAL_PAGE,jsp容器将继续执行jsp页面的内容,否则不执行
F.release()方法:释放标签程序占用的任何资源
Tag例子:
web应用
程序目标:
使用一个简单的自定义标签Tag
名字:ctab
程序逻辑:
1.写标签处理器类:TestTag.java
2.写tld文档:用来指定标签的名字,标签库等
3.用jsp来测试(指定标签库的位置tld,指定前缀名,使用标签)
目录结构:ctab
根目录:
/ctab
/ctab/JS
/ctab/pages: helloTag.jsp
/ctab/pice
/ctab/WEB-INF : web.xml mytag.tld
/WEB-INF/classes
/WEB-INF/lib
/WEB-INF/src : yuchen.ctab.ctab1.TestTag.java
TestTag.java:
package yuchen.ctab.ctab1;
//Tag建议处理空的标签,不要处理正文
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
public class TestTag implements Tag{
private Tag tag=null;
private PageContext pageContext=null;
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
try {
pageContext.getOut().print("hello");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Tag.EVAL_PAGE;//处理完标签后继续执行后面的jsp代码
}
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return Tag.SKIP_BODY;//不处理正文内容
}
public Tag getParent() {
// TODO Auto-generated method stub
return null;
}
public void release() {
// TODO Auto-generated method stub
}
public void setPageContext(PageContext arg0) {
// TODO Auto-generated method stub
pageContext=arg0;
}
public void setParent(Tag arg0) {
// TODO Auto-generated method stub
tag=arg0;//设置上一级标签
}
}
mytag.tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>tagSample</short-name>
<uri>/mytag</uri>
<tag>
<name>hello</name>
<tag-class>yuchen.ctab.ctab1.TestTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
helloTag.jsp:
<%@ page contentType="text/html; charset=ISO-8859-1"
pageEncoding="utf-8"%>
<%@taglib prefix="mytag" uri="/mytag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>hello tag</title>
</head>
<body>
<mytag:hello></mytag:hello>
<mytag:hello/>
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" 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-
app_2_4.xsd">
<display-name>
ctab</display-name>
</web-app>
结果会显示两个hello
指定对标签的引用xml:
web.xml:
<tablib>
<tab-uri>/uri</tab-uri> //要和你定义的标签的uri一样,通过这里找到标签
<tab-location>/WEB-INF/xxx.tld</tab-location>//tld文件的路径
</tablib>
几种典型的自定义标签:
1.<mytab:tab />
2.<mytab:tab name="hello" />
3.<mytab:tab name="hello">hello world!</mytab:tab>
4.Simple2.0中的新增标签
IterationTag接口:用于开发迭代标签
这个接口实现了Tag接口
有个子类:TagSupport类
int doAfterBody() : 处理body
这个方法要想顺利执行,需要满足两个条件:
1.标签要有body,tld中的不能为空
2.doStartTag的返回值必须不能为SKIP_BODY,这个意思是不处理正文
TagSupport类:
这个类实现了IterationTag接口,里面有此接口和Tag接口中的所有方法
可以用这个类定义空的标签
使用TagSupport的例子:
ctab2:
程序目标:
使用TagSupport类,显示hello和日期
标签处理器类:
/*
* 这个标签处理器显示hello和当前时间
*/
package yuchen.ctab.ctab2;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.*;
public class TestTagsupport extends TagSupport{
private PageContext pageContext;
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return Tag.SKIP_BODY;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
try {
pageContext.getOut().print("hello"+new java.util.Date().toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Tag.EVAL_BODY_INCLUDE;
}
@Override
public void setPageContext(PageContext arg0) {
// TODO Auto-generated method stub
this.pageContext=arg0;
}
}
定义标签tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>tagsupport</short-name>
<uri>/mytagsupport</uri>
<tag>
<name>date</name>
<tag-class>yuchen.ctab.ctab2.TestTagsupport</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="mysupport" uri="/mytagsupport" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mysupport:date/>
</body>
</html>
BodyTag接口:处理正文内容(body)
body就是标签体里面的内容,如:<table>body</table>
类似于过滤器的功能,就是将正文结果拿过来进行处理加工
BodyTagAPI+生命周期:
1.setters:jsp容器实例化标签后,根据引入的标签库的uri找到对应的tld文件,找到里面的属性,然后jsp实现类去set这些属性
2.setPageContext(pageContext):设置页面的上下文对象(配置jsp环境)
3.setParent(Tag):设置上一级标签,如果没有上一级标签,设置为null
4.doStartTag():如果返回值为:EVAL_BODY_INCLUDE那么就计算标签里面的内容,SKIP_BODY不进行计算,如果返回BodyTag.EVAL_BODY_BUFFERED就是将正文的内容放到缓冲区里(BodyContent)
5.setBodyContent(BodyContent):设置缓冲区,这个缓冲区可以存放解析后的body
6.doInitBody():为setBodyContent()方法做准备工作,如果在计算setBodyContent()时需要一些初始化,就会调用这个方法
7.doAfterBody():先计算正文内容后,如果doStartTag返回的是EVAL_BODY_INCLUDE,那么执行这个方法,如果此方法返回的是IterationTag.EVAL_BODY_AGAIN,那么就在此计算正文内容,然后再调用此方法
8.doEndTag():如果返回值为EVAL_PAGE容器继续执行jsp页面后面的部分,如果是SKIP_PAGE就不计算了
9.release():释放资源
什么是BodyContent?
bodyContent==jspWriter 就是一个输出流,将body放到这个缓冲区里,以便让标签处理使用这个body,有个getEnclosingWriter()方法这个方法能够得到最终的那个out,但是如果有子标签的话,子标签调用这个方法就不是原始的那个out了
void writeOut(java.io.Writer out):输出这个流里面的内容
getString():得到缓冲区中的内容
引例:根据标签属性的值循环显示标签体中的内容
<attribute>//设置标签属性
<name>counts</name> //属性的名字,需要和标签处理器类中的要一样
<required>true</required> //在jsp中必须写这个属性
<rtexprvalue>true</rtexprvalue> //可以用表达式为属性赋值
</attribute>
标签处理器类:
/*
* 根据属性来控制循环的次数来显示body
*/
package yuchen.ctab.ctab3;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;
public class TestBodyTag extends BodyTagSupport{
private int counts;
public void setCounts(int counts) {
this.counts = counts;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
if((--counts)>0){
System.out.println("doAfterBody:"+counts);
return BodyTag.EVAL_BODY_AGAIN;
}
return BodyTag.SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doEndTag");
if(bodyContent!=null){
try {
//输出缓冲区里面的out中的内容
bodyContent.writeOut(bodyContent.getEnclosingWriter());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return super.doEndTag();
}
@Override
public void doInitBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("initbody");
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
if(this.counts>0){
System.out.println("dostarTag");
return Tag.EVAL_BODY_INCLUDE;
}else{
return Tag.SKIP_BODY;
}
}
@Override
public void setBodyContent(BodyContent arg0) {
// TODO Auto-generated method stub
System.out.println("bodyContent");
bodyContent=arg0;
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>bodytag</short-name>
<uri>/mybody</uri>
<tag>
<name>loop</name>
<tag-class>yuchen.ctab.ctab3.TestBodyTag</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>counts</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="mybody" uri="/mybody" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@page import="java.util.Date"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mybody:loop counts="5">
<%=new Date() %><br>
</mybody:loop>
</body>
</html>
引例:加工缓冲区中的正文内容,测试BodyContent
java类:
package yuchen.ctab.ctab4;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;
public class TestBodyContent extends BodyTagSupport{
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
String content=bodyContent.getString();
content.toUpperCase();
content.replaceAll("/n", "<br>");
content=content+"from TestBodyContent" ;
try {
bodyContent.getEnclosingWriter().print(content);
pageContext.getOut().println(content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Tag.EVAL_PAGE;
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>bodycontent</short-name>
<uri>/mybodycontent</uri>
<tag>
<name>content</name>
<tag-class>yuchen.ctab.ctab4.TestBodyContent</tag-class>
<body-content>jsp</body-content>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="mycontent" uri="/mybodycontent" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mycontent:content>
hello word
</mycontent:content>
</body>
</html>
引例:用标签替换掉if:如果属性为true,那么就执行标签体中的内容,否则不执行后面的内容
java类:
package yuchen.ctab.ctab5;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;
public class IfTag extends TagSupport{
private boolean verily;
public void setVerily(boolean verily) {
this.verily = verily;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
if(verily){
return Tag.EVAL_BODY_INCLUDE;
}
return Tag.SKIP_BODY;
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>iftag</short-name>
<uri>/myif</uri>
<tag>
<name>if</name>
<tag-class>yuchen.ctab.ctab5.IfTag</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>verily</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="myif" uri="/myif" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<myif:if verily="true">hello</myif:if>
<myif:if verily="false">world!</myif:if>
</body>
</html>
自定义标签2.0
Simple的生命周期:
1.在jsp中使用这个标签的实例后,调用setJspContext()
2.调用setParent():这个方法是在有标签嵌套的情况下调用
3.setters
4.setJspBody():如果标签体有body,调用此方法
5.doTag():所有的标签逻辑,业务计算,迭代都在这里实现
6.doTag() return的时候锁定属性值
和1.2的区别:
没有doS,doE方法
doTag()只调用一次
没有标签池,每次再用的话需要从新创建
在body中不能有表达式
API:
SimpleTag接口和SimpleTagSupport实现类
引例1:
程序目标:有if功能的自定义标签
知识点:
1.JspFragment对象,原始body
2.getJspBody()将得到body
3.invoke(null):body的方法,执行body
4.tld的写法:在<body-content>中写scriptless
java类:
package yuchen.ctab.simpleTag.s1;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;
public class SimpleIf extends SimpleTagSupport{
private boolean cond;
public void setCond(boolean cond) {
this.cond = cond;
}
@Override
public void doTag() throws JspException, IOException {
// TODO Auto-generated method stub
JspFragment body=getJspBody();//原始body
if(this.cond){
getJspBody().invoke(null);//执行body
}
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>simpleif</short-name>
<uri>/mysimpleif</uri>
<tag>
<name>if</name>
<tag-class>yuchen.ctab.simpleTag.s1.SimpleIf</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>cond</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="mysimpleif" uri="/mysimpleif" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mysimpleif:if cond="true">
hello world!
</mysimpleif:if>
<mysimpleif:if cond="false">
hello world!
</mysimpleif:if>
</body>
</html>
引例2:
带有while循环功能的标签
知识点:
doTag方法只执行一次
invoke(null)null为默认的输出流,相当于getJspContext().getOut()
java类:
package yuchen.ctab.simpleTag.s2;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.*;
public class SimpleWhile extends SimpleTagSupport{
private int counts;
public void setCounts(int counts) {
this.counts = counts;
}
@Override
public void doTag() throws JspException, IOException {
// TODO Auto-generated method stub
JspFragment body=getJspBody();
for(int i=0;i<this.counts;i++){
body.invoke(null);//null为默认的输出流,相当于
//getJspContext().getOut()
}
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>simplewhile</short-name>
<uri>/mysimplewhile</uri>
<tag>
<name>loop</name>
<tag-class>yuchen.ctab.simpleTag.s2.SimpleWhile</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>counts</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="mysimplewhile" uri="/mysimplewhile" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<mysimplewhile:loop counts="5">
hello world<br>
</mysimplewhile:loop>
</body>
</html>
EL表达式语言:
什么是el表达式语言?作用?
jsp2.0中的body里不能使用表达式,el可以解决这个问题,他的作用就是访问数据
可以访问对象属性,参数,变量,类的静态方法等
可以使用内置对象
运算符丰富
可以和jstl结合使用
语法:
${}
注意:在jsp2.0以前是没有表达式语言的,但是jsp中可以认识${},所以要想正常解析el语言,需要使用page命令
<%@page isEl|gnored="true|false"%>false为解析
访问数据:
访问对象的属性:${对象名.对象属性} 或 ${对象名["对象属性"]}
访问类的静态方法:${前缀:方法名(参数|param.参数)}
访问数组元素:${数组[0]}
运算符:
empty:判断对象是否为空:测试集合,字符串等 ${empty customer.name} 如果name为null,返回true
${!empty customer.name}如果name不为null,返回true
环境配置
容器需要支持2.4,web.xml中也要是2.4
内置对象:
PageContext:ServletContext,request,response,session
param:${param["参数"]} 或者 ${param.参数} 请求参数名集合 例如:表单中参数的名字
paramValues:请求参数值集合 表单中参数值
pageScope:当前页面内所有对象的集合
requestScope:请求范围内所有对象的集合
sessionScope:整个会话中所有对象的集合
applicationScope:web应用范围内所有对象的集合
cookie:所有cookie组成的集合
initParam:web中所有初始化参数名的集合
引例:
stu包:
程序目标:在jsp页面中通过el表达式语言访问一个类中的对象属性
java类:
package yuchen.el.stu;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
public Student() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" import="linshi.el.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="stu" class="yuchen.el.stu.Student"></jsp:useBean>
<jsp:setProperty name="stu" property="*" />
<form action="Testel.jsp" method="get">
username: <input type="text" name="name" /><br>
age: <input type="text" name="age"/>
<input type="submit" />
</form>
<br>
username=${stu.name}
age=${stu.age }
</body>
</html>
引例:
function包:
程序目标:在jsp页面中通过el表达式语言访问java类中的静态方法
知识点:
1.param对象的使用:读取表单参数(两种等价的方式)
2.tld的写法:
<function>
<name>add</name> //方法名字
<function-class>yuchen.el.function.FunctionClass</function-class>//方法所在的类
<function-signature>int add(int,int)</function-signature>//方法的格式
</function>
java类:
package yuchen.el.function;
public class FunctionClass {
public static int add(int a,int b){
return a+b;
}
public static String reverse(String s){
char[] c=s.toCharArray();
int l=c.length;
char[] x=new char[l];
String rst=null;
for(int i=0;i<l;i++){
x[i]=c[l-i-1];
}
rst=String.valueOf(x);
return rst;
}
}
tld:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>function</short-name>
<uri>/function</uri>
<function>
<name>add</name>
<function-class>yuchen.el.function.FunctionClass</function-class>
<function-signature>int add(int,int)</function-signature>
</function>
<function>
<name>reverse</name>
<function-class>yuchen.el.function.FunctionClass</function-class>
<function-signature>java.lang.String reverse(java.lang.String)</function-signature>
</function>
</taglib>
jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="function" uri="/function" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<form>
第一个数 : <input type="text" name="x"/>
第二个数 : <input type="text" name="y"/>
<br>
<input type="submit" value="add"/><br>
结果 : ${function:add(param["x"],param["y"])}
</form>
<hr>
<form>
字符串 : <input type="text" name="s" />
<input type="submit" value="string" />
<br>
结果 : ${function:reverse(param.s) }
</form>
</body>
</html>
标准标签库JSTL:
什么是标准标签库?有什么用?
在jsp1.2中就开始有人用自定义标签来减少代码的复杂度,但是有一些常用的功能标签被重复开发,所以开发了一套
标准标签库jstl,里面有常用功能的标签
分类:
1.core标签
2.url标签
3.xml标签
4.国际化标签
5.sql标签
lib:
jstl.jar standard.jar 这两个是jstl的包
xalan-2.4.0:解析xml的
位置:jps/参考资料/lib中
core标签:
1.<c:out value="要输出的值" [escapeXml="true"] [default="默认的输出值"]>
escapeXml=true:表示<>等符号原样显示
jstl不解析el表达式的解决方法:
将<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
改为<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>,然后重起tomcat
引例1
cout包:
程序目标:测试cout
知识点:
1.<c:cout>相当于jsp中的out
2.value,default属性
3.读取request,session中属性的值
4.验证request,session,appliction的读取顺序
5.在c:out的value里可以使用el表达式语言
jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<hr>不带body的out
<c:out value="hello"></c:out>
<%
session.setAttribute("hello","session hello world!");
request.setAttribute("hello","request hello world!");
application.setAttribute("hello","application hello world!");
%>
<br><hr>
<c:out value="a>b" escapeXml="true"></c:out>
<br>
${hello}
<br><hr>如果没有这个abc属性,显示缺省值
<c:out value="${abc}" default="default"></c:out>
<c:out value="${hello}"></c:out>
</body>
</html>
2.<c:set>
作用:设置el变量,el表达式语言可以使用这个变量,为javabean and map对象属性赋值
语法:
设置变量:<c:set var="el变量" scope="page|request|session|application" value="el变量值">
这句话的意思是,如果scope中没有这个变量,那么就创建该变量,并且将value赋给他,如果有这个变量,就直接赋值
为对象属性赋值:<c:set target="类的对象名字" property="对象属性" value="为属性赋的值">
引例:
cset包:
程序目标:测试cset,声明几个el变量,然后打印出来
知识点:
1.变量的声明赋值
2.给javabean and map 对象属性赋值
3.标签正文中的内容就是value,可以使用el表达式
4.target="${对象名}"
javabean:
package yuchen.jstl.cset;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
public Student() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="yuchen.jstl.cset.Student"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="stu" class="yuchen.jstl.cset.Student" scope="page"></jsp:useBean>
<c:set var="a" scope="page" value="hello"></c:set>
<c:out value="${a}"></c:out><hr>
<c:set var="b" scope="request">${a}</c:set>
<c:out value="${b}"></c:out><hr>
<c:set value="yuchen" target="${stu}" property="name"></c:set>
<jsp:getProperty name="stu" property="name"/><br>
<c:out value="${stu.name}"></c:out>
</body>
</html>
3.<c:remove>:删除变量的值 用法类似于c:set
引例:
cremove包:
程序目标:声明几个变量,然后再删除它们的值
知识点:
1.c:remove可以删除el变量和对象属性的值
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="yuchen.jstl.cset.Student"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="stu" class="yuchen.jstl.cset.Student" scope="page"></jsp:useBean>
<c:set var="a" scope="page" value="hello"></c:set>
<c:out value="${a}"></c:out><hr>
<c:set var="b" scope="request">${a}</c:set>
<c:out value="${b}"></c:out><hr>
<c:set value="yuchen" target="${stu}" property="name"></c:set>
<jsp:getProperty name="stu" property="name"/><br>
<c:out value="${stu.name}"></c:out>
</body>
</html>
4.<c:catch>:捕获异常,相当于try,一般是使用一个errorage来处理异常,用的不多
引例:
ccatch包:
程序目标:测试catch捕获异常的能力
知识点:
1.var:声明异常对象,这是el变量
2.打印异常信息:声明异常对象.message 相当于 声明异常对象.getMessage();
jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h3>捕获异常</h3>
<c:catch var="execption">
<%
int i=10;
int j=0;
int rst;
rst=i/j;
%>
</c:catch>
<c:out value="${execption}"></c:out>
<c:out value="${execption.message}"></c:out>
<c:out value="${execption.cause}"></c:out>
</body>
</html>
5.条件标签:<c:if>
引例:
If包:
测试if标签
知识点:
这样判断${变量>10},不要写成${变量}>10
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="stu" class="yuchen.jstl.term.If.Student"></jsp:useBean>
<c:set target="${stu}" property="age" value="20"></c:set>
<c:if test="${stu.age>10}" >hello world!</c:if><hr>
<c:set var="a" value="30" />
<c:if test="${a>10}">hello world!</c:if>
</body>
</html>
6.条件标签:<c:choose> <c:when> <c:otherwise>
作用:相当于switch case
引例:
switch包:
程序目标:得到表单参数,如果是china 那么输出一些内容,如果是日本,输出一些内容,其他输出一些内容
知识点:
使用标签代替switch case语法
jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="choose.jsp">
请输入您的国籍:<input type="text" name="age" />
<input type="submit" />
</form>
<hr>
<c:choose>
<c:when test="${param.age=='china'}" >
<c:out value="我们都一个家名字叫中国" />
</c:when>
<c:when test="${param.age=='Japanese'}" >
<c:out value="想起沉痛的历史"/>
</c:when>
<c:otherwise>
<c:out value="默认"/>
</c:otherwise>
</c:choose>
</body>
</html>
7.迭代标签:foreach
语法:
var:el变量,用来存放集合中的元素
items:这里放集合
begin:int i=? 开始的数
end:结束条件
step:迭代的步长
varStatus:迭代的状态:状态变量.index:得到索引号 状态变量.count:得到当前集合的数量first:判断该元素是不是开头的元素
last:判断该元素是不是最后一个元素
引例:简单的迭代标签
foreach包:
程序目标:创建一个学生的集合,然后使用for eatch标签显示出来
知识点:简单的foreach
java类:
package yuchen.jstl.Iterator.foreach;
import java.io.Serializable;
public class User implements Serializable{
private String userName;
private String password;
public User() {
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="yuchen.jstl.Iterator.foreach.User,java.util.*"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<%
Collection users=new ArrayList();
for(int i=0;i<5;i++){
User user=new User();
user.setUserName("zhangsan"+i);
user.setPassword("123"+i);
users.add(user);
}
session.setAttribute("users",users);
%>
<table align="center" border="1">
<c:forEach var="user" items="${users}">
<tr>
<td>${user.userName}</td>
<td>${user.password}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
引例:
foreach2包:
程序目标:测试固定次数的循环功能
知识点:固定次数的迭代 模拟for(int i;i<length;i++)
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:forEach begin="1" end="10" step="1" var="i">
<c:out value="${i}"></c:out>
</c:forEach>
<hr>
<c:forEach begin="1" end="10" step="2" var="i">
<c:out value="${i}"></c:out>
</c:forEach>
</body>
</html>
8.迭代标签:forTokens
作用:分割字符串的循环标签,相当于StringToken工具类
引例:
foreach3包:
程序目标:分割一个字符串,以逗号分割
知识点:模拟StringToken的功能
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:forTokens items="hello,world,!" delims="," var="i">
<c:out value="${i}"></c:out><br>
</c:forTokens>
</body>
</html>
url标签:
1.<c:import>
倒入url资源,这个资源可以是外部的
引例:
url包:url相关的标签
<c:import>包含一个倒入的url资源,可以是外部资源
jsp:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
hello world!
<c:import url="choose.jsp"></c:import>
</body>
</html>
2.<c:url>
书写url用的标签,里面可以加上参数标签<c:param>
引例:
url包:url相关的标签
<c:url>书写一个url,在这个标签中可以写<c:param>加入参数
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:url value="import.jsp" var="i" scope="request">
<c:param name="age" value="china"></c:param>
</c:url>
<A href="<c:out value="${i}"></c:out>">lalala</A>
</body>
</html>
3.<c:redirect>
转到指定的页面
引例:
url包:url相关的标签
<c:redirect>转到指定的页面
<c:param>设置参数,可以用在import,url,redirect中
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:url value="import.jsp" var="i">
<c:param name="age" value="china"></c:param>
</c:url>
<c:redirect url="${i}"></c:redirect>
</body>
</html>
也可以这么写:
jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:redirect url="import.jsp">
<c:param name="age" value="china"></c:param>
</c:redirect>
</body>
</html>
Xml标签 and Sql标签:用的情况少,暂时跳过