学会怎样使用Jsp 内置标签、jstl标签库及自定义标签
学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签。
jsp标签的分类:
1)内置标签(动作标签): 不需要在jsp页面导入标签
2)jstl标签: 需要在jsp页面中导入标签
3)自定义标签 : 开发者自行定义,需要在jsp页面导入标签
1、内置标签(动作标签):
语法:
相当于java代码:request.getRequestDispatcher("/MyJsp001.jsp?name=jxf").forward(request, response);
注意:但是java代码的转发可以通过url带参数的方式进行传递参数,而转发标签需要借助于下面的
语法:
结合
语法:
jsp中还有一个包含指令,也是将一个页面包含另外的页面
他们之间的区别:
1、首先是语法不同
<%@inclue file="被包含的页面"%>
2、
3、
<%@inclue%>:包含页面与被包含页面合并编译为一个java源文件
2、jstl标签:
JSTL (java standard tag libarary - java标准标签库)
jstl标签的类型:
核心标签库 (c标签库)//这里主要介绍c标签库,因为用的真的很多
国际化标签(fmt标签库)
EL函数库(fn函数库)
xml标签库(x标签库)//一般不用该库,这属于数据操作,而数据操作应于dao层中,jsp页面主要用于展示数据
sql标签库(sql标签库)//与xml标签库类似,不应在jsp页面中操作数据(当然他们是可以在jsp页面写)
使用jstl标签库使用前提(此处以c标签库为例):
1、导入jstl支持包:jstl-1.2.jar(如果用MyEclipse创建项目时候选择java EE5.0,则不需要导包,工程中已经包含)
2、在页面中使用Taglib指令导入标签库
<%--uri:tld文件中的uri名称,prefix:标签前缀--%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
uri和prefix怎样写?以标签库的为例:
工程名->Java EE 5 Libraries->jstl-1.2.jar->META-INF-c.tld
c标签库的主要标签:
<%--var为属性名 value为属性值 scope为保存属性到那个域对象,默认为page域 --%>
<%--相当于java代码<%pageContext.setAttribute("name", "jxf") --%>
${name}<%--EL表达式输出page域中的name属性值--%>
<%--value:输出到浏览器的值,${name}EL表达式取出域对象属性值为name的值, default:当value值为null时显示的默认值, escapeXml:表示是否转义为xml格式(也可以理解为普通文本格式),true表示转义,默认false --%>
<%--test支持EL表达式 --%>
条件成立!
<%--相当于if else结构,当有一条件满足后其他条件都不满足,证:此实例只输出 10>5--%>
10>5
6>2
条件都不成立
<%--
begin : 从哪个元素开始遍历,默认从0开始
end : 到哪个元素结束。默认到最后一个元素
step : 步长,默认1
items : 需要遍历的数据(集合)
var : 每个元素的名称
varStatus: 当前正在遍历元素的状态对象。(count属性:当前位置,从1开始) --%>
<%
//Student{ // public String name; // public int age; // public Student(String Name,int Age){ // this.name = Name; // this.age = age; // } //}
//List数据准备
List
list.add(new Student("name001",18));
list.add(new Student("name002",19));
list.add(new Student("name003",20));
pageContext.setAttribute("list",list);//放入域中
//Map数据准备
Map
map.put("001",new Student("name001",18));
map.put("002",new Student("name002",19));
map.put("003",new Student("name003",20));
pageContext.setAttribute("map",map);//放入域中
//array数据准备
Student[] array = new Student[]{
new Student("name001",18),
new Student("name002",19),
new Student("name003",20)};
pageContext.setAttribute("array",array);//放入域中
%>
<%--遍历list --%>
name:${student.name}---age:${student.age}
<%--遍历map --%>
key:${student.key}---name:${student.value.name}---age:${student.value.age}
<%--遍历array --%>
name:${student.name}---age:${student.age}
<%--一般遍历集合或者数组都是全部遍历,所以只写2个属性var和items,其他取默认值 --%>
name:${student.name}---age:${student.age}
<%--
切割字符串,相当于split函数
var:切割出来的每一部分字符串
items:要切割的字符串
delims:分割的字符,若内容为字符串,则这个字符串的每个字符都会当作一个分割的字符
如:items="a-b-c=d=e" dilims="-=",分割的结果为 a,b,c,d,e
--%>
<%
//数据准备
String str = "a-b-c=d=e";
pageContext.setAttribute("str", str);
%>
${item}
3、自定义标签:
当JSTL标签库已经无法满足我们的需求时候,就需要自己开发自定义标签,来满足我们的需求,自定义标签实际上是一个普通的java类,继承SimpleTagSupport类。
在介绍自定义标签之前,先介绍SimpleTagSupport类:
SimpleTagSupport类继承自SimpleTag接口,而SimpleTag接口主要有以下4个方法,也可将这四个方法理解为标签处理器类的生命周期:
1 public interface SimpleTag extends JspTag {
2
3 /**
4 * 执行标签时调用的方法,一定会调用
5 */
6 public void doTag() throws javax.servlet.jsp.JspException, java.io.IOException;
7
8 /**
9 * 设置父标签对象,传入父标签对象,当标签存在父标签时会调用
10 */
11 public void setParent( JspTag parent );
12
13 /**
14 * 设置JspContext对象,其实他真实传入的是其子类PageContext
15 */
16 public void setJspContext( JspContext pc );
17
18 /**
19 * 设置标签体内容。标签体内容封装到JspFragment对象 中,然后传入JspFragment对象
20 */
21 public void setJspBody( JspFragment jspBody );
22
23 }
SimpleTagSupport类在其基础上封装出了3个方法,方便自定义标签类编写,该方法实现也比较简单,无非就是内部维护一个变量,通过set方法将其赋值,再返回该对象,这样继承SimpleTagSupport拿到如PageContext对象就直接调用getJspContext()即可。
1 /*SimpleTagSupport 类的一部分*/
2 public class SimpleTagSupport implements SimpleTag
3 {
4 /** Reference to the enclosing tag. */
5 private JspTag parentTag;
6
7 /** The JSP context for the upcoming tag invocation. */
8 private JspContext jspContext;
9
10 /** The body of the tag. */
11 private JspFragment jspBody;
12
13 public void setParent( JspTag parent ) {
14 this.parentTag = parent;
15 }
16
17 public JspTag getParent() {
18 return this.parentTag;
19 }
20
21 public void setJspContext( JspContext pc ) {
22 this.jspContext = pc;
23 }
24
25 protected JspContext getJspContext() {
26 return this.jspContext;
27 }
28
29 public void setJspBody( JspFragment jspBody ) {
30 this.jspBody = jspBody;
31 }
32
33 protected JspFragment getJspBody() {
34 return this.jspBody;
35 }
36 }
编写自定义标签的步骤:
以写一个自定义标签为例:功能:向浏览器输出一句话“酒香逢 博客园欢迎您”
1)编写一个普通的java类(OutInfo.java),继承SimpleTagSupport类,并重写doTag方法。(jsp文件最后编译为java文件,查看该java文件可知_jspService方法中,会创建标签类OutInfo对象,并执行doTag方法。编译后原文件路径:如D:\Program Files\Tomcat\apache-tomcat-6.0.39\work\Catalina\localhost\Tag\org\apache\jsp\xxx.java)
1 /*
2 * OutInfo.java
3 */
4 public class OutInfo extends SimpleTagSupport {
5
6 @Override
7 public void doTag() throws JspException, IOException {
8 PageContext pageContext = (PageContext)getJspContext();
9 pageContext.getOut().write("酒香逢 博客园欢迎您");
10 }
11 }
2)在web项目的WEB-INF目录下建立tld文件(jxf.tld),这个tld文件为标签库的声明文件,并配置好相应的信息。(可以参考核心标签库的tld文件,如:项目/Java EE 5 Libraries/jstl-1.2jar/META-INF/c.tld)
1
2
3 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" 6 version="2.1"> 7 8 9 10 11 12 13 14 15 16 17 18 这是自定义标签的描述信息,可以在MyEclipse中有提示 19 20 21 22 23 24 25 33 34 35
3)在jsp页面的头部导入自定义标签库
<%@taglib uri="http://jxf.tag" prefix="jxf" %>
4)在jsp中使用自定义标签
5)jsp页面
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2 <%@taglib uri="http://jxf.tag" prefix="jxf" %>
3
4
5
6
7
8
9
10
11
自定义标签能够做的:
1)控制标签体内容输出
1 /*
2 * 1)输出标签题内容
3 */
4 JspFragment jspBody = getJspBody();
5 //方法:invoke(java.io.Writer out)
6 //当参数为null时等价于 jspBody.invoke(getJspContext().getOut());
7 jspBody.invoke(null);
2)控制标签余下内容输出
1 /*
2 * 2)控制标签体余下内容是否输出
3 * 抛出一个SkipPageException异常后,标签体余下内容输出
4 */
5 throw new SkipPageException();
3)改变标签体内容
1 /*
2 * 3)改变标签体内容并输出到浏览器
3 */
4 //获取到标签体内容,并保存到自定义的款冲字符流中
5 StringWriter sw = new StringWriter();
6 //jspBodyString得到的即是标签体的内容
7 String jspBodyString = sw.toString();
8 jspBodyString = "简单将字符串的值改变掉";
9 getJspContext().getOut().write(jspBodyString);//输出到浏览器
4)带属性的标签(以模仿c标签的
编写3个自定义标签处理器类 ChooseTag.java、 When.java、 Otherwise.jave
1 /*
2 * ChooseTag.java
3 */
4 public class ChooseTag extends SimpleTagSupport {
5 private boolean flag = false;
6
7 public boolean isFlag() {
8 return flag;
9 }
10
11 public void setFlag(boolean flag) {
12 this.flag = flag;
13 }
14 @Override
15 public void doTag() throws JspException, IOException {
16 getJspBody().invoke(null);
17 }
18 }
/*
* WhenTag.java
*/
public class WhenTag extends SimpleTagSupport {
private boolean test;
//tld文件中的属性必须要有对应的set方法,否则报错
public void setTest(boolean test) {
this.test = test;
}
@Override
public void doTag() throws JspException, IOException {
ChooseTag parent = (ChooseTag)getParent();
if(!parent.isFlag()){
if(test){
parent.setFlag(true);
getJspBody().invoke(null);
}
}
}
}
1 /*
2 * OtherwiseTag.java
3 */
4 public class OtherwiseTag extends SimpleTagSupport {
5 @Override
6 public void doTag() throws JspException, IOException {
7 ChooseTag parent = (ChooseTag)getParent();
8 if(!parent.isFlag()){
9 getJspBody().invoke(null);
10 }
11 }
12 }
tld文件
1
2
3 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" 6 version="2.1"> 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 自定义的when标签 24 25 26 27 28 29 30 when标签属性test 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
jsp代码
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
2 <%@taglib uri="http://jxf.tag" prefix="jxf"%>
3
4
5
6
7
8
9
10 标签体余下内容
11
12
13
14 4>5是不输出的
15
16
17 10>5是成立的
18
19
20 9>5是成立的,但是不输出
21
22
23 当条件都不成立时候输出(由于第二个提条件成立,故不应输出)
24
25
26
27