学习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带参数的方式进行传递参数,而转发标签需要借助于下面的标签实现参数传递
语法: <%-- 传递一个名为name,值为jxf的参数,参数一般作为其他标签的子标签使用--%>
结合标签用法:
语法:
<%--可以将参数传递给包含进来的页面--%>
jsp中还有一个包含指令,也是将一个页面包含另外的页面
他们之间的区别:
1、首先是语法不同
<%@inclue file="被包含的页面"%>
2、可以传递参数,<%@inclue%>不可以
3、:包含页面与被包含页面分别编译为两个java源文件,在运行时引用
<%@inclue%>:包含页面与被包含页面合并编译为一个java源文件
JSTL (java standard tag libarary - java标准标签库)
jstl标签的类型:
核心标签库 (c标签库)//这里主要介绍c标签库,因为用的真的很多
国际化标签(fmt标签库)
EL函数库(fn函数库)
xml标签库(x标签库)//一般不用该库,这属于数据操作,而数据操作应于dao层中,jsp页面主要用于展示数据
sql标签库(sql标签库)//与xml标签库类似,不应在jsp页面中操作数据(当然他们是可以在jsp页面写)
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
<%--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 = new ArrayList();
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 = new HashMap();
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}
当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
7
8 JSTL 1.1 core library
9 JSTL core
10 1.1
11
12 jxf
13
14 http://jxf.tag
15
16
17
18 这是自定义标签的描述信息,可以在MyEclipse中有提示
19
20
21 outInfo
22
23 jxf.OutInfo
24 scriptless
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
7
8 JSTL 1.1 core library
9 JSTL core
10 1.1
11
12 jxf
13
14 http://jxf.tag
15
16
17 chooseTag
18 jxf.ChooseTag
19 scriptless
20
21
22
23 自定义的when标签
24
25 whenTag
26 jxf.WhenTag
27 scriptless
28
29
30 when标签属性test
31
32
33 test
34
35 true
36
37 true
38
39
40
41 otherwiseTag
42 jxf.OtherwiseTag
43 scriptless
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 模仿c标签库的choose,when,otherwise
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