JavaWeb从入门到精通(视频实战版)
上QQ阅读APP看书,第一时间看更新

2.4 编译指令和动作标签

编译指令主要用来提供整个JSP网页相关的信息,并且用来设定JSP网页的相关属性,例如:网页的编码方式、语法、信息等。起始符号为“<%@”,终止符号为“%>”,中间部分就是一些指令和一连串的属性设定。JSP有3个编译指令:page、include和taglib。

动作标签又称为动作元素、动作指令,也可以理解为JSP自带的标准标签库。动作标签利用XML语法格式的标记来控制JSP服务器的行为。利用动作标签可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。动作标签起始符号为<jsp:xxx>,终止符号为</jsp:xxx>。

2.4.1 使用page指令

page指令是最复杂的编译指令,它的主要功能为设定整个JSP网页的属性和相关功能。page指令的基本语法如下:

<%@ page attribute1="value1" attribute2= "value2" attribute3=...%>

如:

<%@ page import="java.util.* java.lang.*" %>
<%@ page buffer="5kb" autoFlush="false" %>
<%@ page errorPage="error.jsp" %>

page指令有13个属性,如表2.3所示。

表2.3 page指令属性

可以把page指令放在JSP的文件任意位置,但它的作用范围始终都是整个JSP页面。为了提高JSP程序的可读性,以及养成好的编程习惯,最好还是把它放在JSP文件的顶部。可以在一个页面中用上多个<%@page%>指令,但是其中的属性只能用一次。不过也有个例外,那就是import属性,这和Java中的import非常类似,可以使用多个import来引入类,它也是最常用的属性。

2.4.2 用include指令插入其他JSP

include指令是在JSP中包含一个静态的文件,同时解析这个文件中的JSP语句。include指令只有一个参数,就是要插入文件的相对路径。语法如下:

<%@ include file="relativeURL" %>

include指令将会在JSP编译时插入一个包含文本或代码的文件,当使用include指令时,这个包含的过程是静态的。也可以理解为不管要插入的文件内容是什么,简单地把其中所有的内容拷贝过来合并成一个新文件,然后提交给JSP服务器做接下来的工作。由此可以看出,如果两个文件中有重复的Java变量或函数定义,那么合并之后编译要出错,HTML的标签也同样会相互影响,要避免片段文件中有<html><body>之类的全局标签出现。

这里提到的静态文件的意思是,引入文件名不能是一个变量,只能是一个静态的字符串。最后一点,如果这个片段文件被改变,那么包含此文件的JSP文件将被重新编译,因为是先插入再整体编译,片段改变相当于整个合并后的JSP改变了,当然需要重新编译。

2.4.3 用taglib指令引入标签库

taglib指令能够让用户自定义新的标签。这里只是先做一个简单介绍,在后面的章节再详细介绍如何自定义标签和如何使用标签。taglib指令的语法如下:

<%@ taglib uri = "tagLibraryURI" prefix="tagPrefix" %>

和所有JSP标签元素一样,taglib指令也支持XML语法。参数如表2.4所示。

表2.4 taglib指令参数表

2.4.4 用forward标签跳转页面

forward动作把请求转到另外的页面。<jsp:forward>标签只有一个属性page。page属性包含的是一个相对URL。page的值既可以直接给出,也可以在请求的时候动态计算。如下面的例子所示:

<jsp:forward page="/utils/errorReporter.jsp" />
<jsp:forward page="<%=someJavaExpression%>" />

2.4.5 动态插入文件

<jsp:include>标签把指定文件插入到正在生成的页面。其语法如下:

<jsp:include page="relative URL" flush="true" />

参数说明见表2.5。

表2.5 <jsp:include>标签参数表

所谓动态插入,正是相对于前面已经介绍过的静态include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的<jsp:include>动作不同,插入文件的时间是在页面被请求的时候。这里被插入的文件是一个完整的JSP文件而非片段,把两个JSP输出到客户端的结果结合在一起,它们分别被JSP服务器转化为两个不同Java类,因此不存在变量定义方面的冲突。用<jsp:include>标签引入文件的效率要稍微差一点,而且被引用文件不能包含某些JSP代码(例如不能设置HTTP头),但它的灵活性却要好得多。

又与静态插入不同,引入文件名可以是一个变量或者表达式。如果这个片段文件被改变,那么只是这个文件本身重新编译而包含此文件的JSP文件不会被重新编译。

2.4.6 用标签操作JavaBean

本节将涉及3个标签:<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>。

<jsp:useBean>标签用来装载一个将在JSP页面中使用的JavaBean。这个功能非常有用,因为它使得开发人员既可以发挥Java组件重用的优势,同时也避免了直接在JSP实例化对象的复杂操作。<jsp:useBean>标签最简单的语法为:

<jsp:useBean id="name" class="package.class" />

参数见表2.6。

表2.6 <jsp:useBean>标签参数表

获得Bean实例之后,要设置Bean的属性可以通过<jsp:setProperty>标签,要读取Bean的属性就用<jsp:getProperty>。这两个标签的语法如下:

<jsp:setProperty name="myName" property="someProperty" value="value" />
<jsp:getProperty name="myName" property="someProperty" />

实例2-6是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。

【实例2-6】动作标签BeanTest.jsp示例

01   <html>
02     <head>
03        <title>Bean动作标签</title>
04     </head>
05     <body>
06        <!--使用JSP编译指令定义Bean-->
07        <jsp:useBean id="test" class=" com.book.web3.SimpleBean" />
08        <!--使用JSP编译指令给Bean赋值-->
0 9        <jsp:setProperty name="test" property="message" value="Hello reader" />
10        刚刚赋值的消息:<jsp:getProperty name="test" property="message" />
11        <br>
12     </body>
13   </html>

图2.17 测试页面

【运行程序】浏览该页面,结果如图2.17所示。

【代码剖析】上面代码中首先通过第7行创建了一个名为test的JavaBean,然后通过第9行设置JavaBean中属性message的值为Hello reader,最后通过第10行输出JavaBean中属性message的值。

BeanTest页面用到了一个SimpleBean类,具体内容如实例2-7。

【实例2-7】动作标签示例涉及的SimpleBean

01   package com.book.web3;
02   public class SimpleBean {
03     // 属性定义
04     private String message = "No message specified";
05     // 属性的getter/setter方法
06     public String getMessage() {
07        return (message);
08     }
09     public void setMessage(String message) {
10        this.message = message;
11     }
12   }

【代码剖析】上面代码中首先在第4行创建了一个名为message的属性,然后分别在第6行和第9行设置该属性的getXXX()和setXXX()方法。

<jsp:getProperty>标签提取指定Bean属性的值,转换成字符串,然后输出。<jsp:getProperty>有两个必需的属性,参数见表2.7。

表2.7 <jsp:getProperty>标签参数表

<jsp:setProperty>用来设置已经实例化的Bean对象的属性,有4个属性,参数见表2.8。

表2.8 <jsp: setProperty>标签参数表

需要说明的是,value属性字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如“true”)通过Boolean.valueOf转换,int和Integer类型的属性值(比如“42”)通过Integer.valueOf转换。value和param不能同时使用,但可以使用其中任意一个。

2.4.7 其他动作标签

<jsp:plugin>标签用来根据浏览器的类型,插入通过Java插件运行Java Applet所必需的OBJECT或EMBED元素。当JSP网页被编译后送往浏览器执行时,<jsp:plugin>将会根据浏览器的版本替换成<object>标签或者<embed>标签。一般来说,<jsp:plugin>会指定对象Applet或Bean,同样也会指定类的名字和位置,另外还会指定将从哪里下载这个Java组件。

<jsp:fallback>一段文字用于:当不能启动Applet或Bean时,那么浏览器会显示一段错误信息。

<jsp:params>标签用来提供key/value的信息,它也可以与<jsp:include>、<jsp:forward>和<jsp:plugin>一起搭配使用。实例2-8展示了这3个标签的用法。

【实例2-8】<jsp:plugin>标签示例pluginTag.jsp

01   <jsp:plugin type="applet" code="Molecule.class" codebase="/html">
02     <jsp:params>
03        <jsp:param name="molecule" value="molecules/benzene.mol" />
04     </jsp:params>
05     <jsp:fallback>
06        <p>Unable to start plugin</p>
07     </jsp:fallback>
08   </jsp:plugin>

【代码剖析】上面代码中首先在第2行到第4行间创建了一个名为molecule的参数,然后在第5行到第7行间通过标签<jsp:fallback>显示出错时的内容。

<jsp:element>、<jsp:attribute>和<jsp:body>标签是JSP 2.0新增的,用来动态定义XML元素。实例2-9展示了这3个标签的用法。

【实例2-9】XML标签示例xmlTag.jsp

01   <jsp:element name="firstname">
02   <jsp:attribute name="name">Mike</jsp:attribute>
03   <jsp:body>Hello</jsp:body>
04   </jsp:element>

【运行程序】执行该代码,其结果如下:

<firstname name="Mike">Hello</firstname>【代码剖析】上面代码中首先在第1行创建一个名为firstname的元素,然后在第2行为该元素创建了一个名为name的属性,同时设置该属性的值Mike,最后在第3行设置该元素的主体为Hello。