Java EE 程序设计
上QQ阅读APP看书,第一时间看更新

4.4 指令

JSP指令是从JSP向Web容器发送的消息,它用来设置页面的全局属性,如输出内容类型等。指令不向客户端输出任何具体内容。指令的作用范围仅限于包含指令本身的JSP页面。

JSP的指令格式为:

    <%@ 指令名 属性="属性值"%>。

指令名有page、include和taglib三种。taglib指令允许页面使用扩展标记。本节主要讲述page指令和include指令。

4.4.1 page指令

page指令用来定义整个JSP页面的全局属性。合法的page属性有import、contentType、isThreadSafe、session、buffer、autoflush、extends、info、errorPage、isErrorPage和language等。下面重点介绍一些最常用的属性。

1.language属性

language属性用来指明JSP页面脚本使用的编程语言。目前JSP页面中language属性的合法值只有一个,那就是"java"。

用法示例:

    <%@ page language="java" %>

2.import属性

import属性用来向JSP页面载入包。

用法示例:

    <%@ page import="java.util.*" %>

注意:包名要用引号引起。如用一个import载入多个包,则用逗号隔开。如:

    <%@ page import="java.util.*, java.lang.*" %>。

3.session属性

session属性指定JSP页面是否支持会话。默认情况下session的值为true。

用法示例:

    <%@ page session="true or false" %>。

下面通过一个例子来说明session属性的作用。向Web应用JspBasic中添加页面jspSession.jsp。完整代码如程序4-8所示。

程序4-8:jspSession.jsp

    <%@ page language="java" %>
    <%@ page session="false"%>
    <%
    if(session.getAttribute("name")==null)
        session.setAttribute("name", "hyl");
    %>
    <% out.println(session.getAttribute("name")); %>

在“项目”视图中选中文件jspSession.jsp,右击,在弹出的快捷菜单中选中“编译文件”命令,在NetBeans底部的输出窗口中将显示编译错误信息,提示变量session找不到,这是因为<%@ page session="false"%>指明页面不支持会话,当编译语句<% out.println (session.getValue("name")); %>时必然会提示出错信息。将<%@ page session="false"%>改为<%@ page session="true"%>,则程序编译通过。

4.errorPage属性

当JSP页面程序发生错误时,由页面的errorPage属性指定的程序来处理。首先生成错误信息处理页面error.jsp。完整代码如程序4-9所示。

程序4-9:error.jsp

    <%@page contentType="text/html"%>
    <%@page pageEncoding="UTF-8"%>
    <html>
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <title>JSP Page</title>
        </head>
        <body>
        <h1>出错啦!! </h1>
        </body>
    </html>

下面通过向Web应用JspBasic中添加页面testError.jsp来说明errorPage属性的作用。完整的代码如程序4-10所示。

程序4-10:testError.jsp

    <%@ page language="java" %>
    <%@ page contentType="text/html; charset=GB2312" %>
    <%@ page errorPage="error.jsp" %>
    <! DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
    <html>
    <head>
    <title>页面错误属性测试</title>
    </head>
    <body bgcolor="#FFFFFF">
    <%! int[] a={1,2,3}; %>
    <%=a[3]%>
    </body>
    </html>

程序说明:页面的errorPage属性指定如果当前页面发生错误时,将导向页面error.jsp。在后面的代码中,发生数组索引越界,将程序导向errorPage属性指定的错误页面。

保存程序并重新发布Web应用,打开IE浏览器,在地址栏中输入http://localhost:8080/JspBasic/testError.jsp,得到如图4-9所示的运行结果页面。

图4-9 errorPage属性测试运行结果

5.contentType属性

contentType属性指定了MIME的类型和JSP文件的字符编码方式,它们都是最先传送给客户端,使得客户端可以决定采用什么方式来展现页面内容。MIME类型有text/plain、text/html(默认类型)、image/gif和image/jpeg等。JSP默认的字符编码方式是ISO 8859-1。

6.isThreadSafe属性

isThreadSafe属性设置JSP文件是否能多线程使用,属性值有true和false两种,默认值是true,也就是说,JSP能够同时处理多个用户的请求,如果设置为false,一个JSP只能一次处理一个请求。下面通过向JspBasic应用中添加页面safe.jsp来说明isThreadSafe属性在保证页面线程安全上的作用。完整的代码如程序4-11所示。

程序4-11:safe.jsp

    <%@ page contentType="text/html; charset=GB2312" %>
    <HTML>
    <BODY>
        <%! int number=0;
        void countPeople()
          {
          int i =0;
          double sum = 0.0;
          while (i++ < 200000000) {
                sum += i;
        }
          number++;
          }
        %>
        <% countPeople();  //在程序片段中调用方法
        %>
    <P>您是第   <%=number%>个访问本站的客户。
    </BODY>
    </HTML>

保存程序并重新发布Web应用,打开IE浏览器,在地址栏中输入http://localhost:8080/JspBasic/safe.jsp,得到如图4-10所示的运行结果页面。

图4-10 JSP线程安全属性测试运行结果

打开一个新的浏览器对话框,在地址栏中输入http://localhost:8080/JSPBasic/safe.jsp,按照程序逻辑设计,页面应该显示“您是第2个访问本站的客户”,但却得到与图4-10相同的结果。为什么会产生错误呢?因为在页面中声明的变量number是JSP页面转化成的Servlet实例所拥有,它为Servlet的所有的线程共享。页面第一次访问后,由于服务器延迟,还没有来得及更新这个变量的值,这时,服务器接收到一个对此Servlet的新请求,Servlet产生一个新的线程,这个线程来访问变量number。正是由于线程之间的不同步,造成了上述错误。

如果在程序第二行加入代码<%@ page isThreadSafe="true" %>,则保证了页面以单线程执行,就从根本上避免了由于线程同步错误的发生。可以在修改页面后重新发布Web应用验证上面的错误是否还会发生。

最后,对于page指令,需要说明的是:

(1)<%@ page %>指令作用于整个JSP页面,同样包括静态的包含文件。但是<%@page %>指令不能作用于动态的包含文件,比如<jsp:include>。

(2)可以在一个页面中引用多个<%@ page %>指令,但是其中的属性只能用一次,不过也有例外,那就是import属性。因为import属性和Java中的import语句类似(参照Java语言,import语句引入的是Java语言中的类),所以此属性就能多用几次。

(3)无论把<%@ page %>指令放在JSP的文件的哪个地方,它的作用范围都是整个JSP页面。不过,为了JSP程序的可读性及良好的编程习惯,最好还是把它放在JSP文件的顶部。

4.4.2 include指令

include指令向JSP页面内某处嵌入一个文件。这个文件可以是HTML文件、JSP文件或其他文本文件。需要着重说明的是,通过include指令包含的文件是由JSP分析的,并且这部分分析工作是在转换阶段(JSP文件被编译为Servlet时)进行的。

用法示例:

    <%@include file="relative url"%>

版权保护信息页面是许多网页经常需要包含的,下面通过include指令向JSP页面嵌入版权信息页面来演示include指令的使用。首先向JspBasic应用中添加使用include指令的页面include.jsp,完整的代码如程序4-12所示。

程序4-12:include.jsp

    <%@ page contentType="text/html; charset=GB2312" %>
    <html>
    <BODY >
    <h1>include示例</h1>
    <H3>
      <%@ include file="copyright.html" %>
    </H3>
    </BODY>
    </HTML>

下面生成版权保护信息页面copyright.html。完整的代码如程序4-13所示。

程序4-13:copyright.html

    <! DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
    <html>
    <head>
    <title> </title>
    </head>
    <body bgcolor="#FFFFFF">
    <HR>
    <h3>All the rights are reserved</h3>
    </body>
    </html>

保存程序并重新发布Web应用,打开IE浏览器,在地址栏输入http://localhost:8080/JspBasic/include.jsp,得到如图4-11所示的运行结果页面,可以看到版权信息已被include指令导入。

图4-11 通过include指令导入页面