JSP 的编译指令是通知 JSP 引擎的消息,它不直接生成输出。编译指令都有默认值,因此开发人员无须为每个指令设置值。
常见的编译指令有如下三个。
➢ page:该指令是针对当前页面的指令。
➢ include:用于指定包含另一个页面。
➢ taglib:用于定义和访问自定义标签。
使用编译指令的语法格式如下:
<%@ 编译指令名 属性名="属性值"···%>
下面主要介绍 page 和 include 指令,关于 taglib 指令,将在自定义标签库处详细讲解。
page 指令
page 指令通常位于 JSP 页面的顶端,一个 JSP 页面可以使用多条 page 指令。page 指令的语法格式如下:
<%@page
[language="Java"]
[extends="package.class"]
[import="package.class | package.*,..."]
[session="true | false"]
[buffer="none | 8KB | size Kb"]
[autoFlush="true | false"]
[isThreadSafe="true | false"]
[info="text"]
[errorPage="relativeURL"]
[contentType="mimeType[;charset=characterSet]" | "text/html;charSet=ISO-8859-1"]
[pageEncoding="ISO-8859-1"]
[isErrorPage="true | false"]
%>
下面依次介绍 page 指令各属性的意义。
➢ language:声明当前 JSP 页面使用的脚本语言的种类,因为页面是 JSP 页面,该属性的值通常都是 java,该属性的默认值也是 java,所以通常无须设置。
➢ extends:指定 JSP 页面编译所产生的 Java 类所承的父类,或所实现的接口。
➢ import: 用来导入包。下面几个包是默认自动导入的,不需要显式导入。默认导入的包有:java.lang.、javax.servlet.、javax.servlet.jsp.、javax.servlet.http.。
➢ session:设定这个 JSP 页面是否需要 HTTP Session。
➢ buffer:指定输出缓冲区的大小。输出缓冲区的 JSP 内部对象:out用于缓存 JSP 页面对客户浏览器的输出,默认值为 8KB,可以设置为 none,也可以设置为其他的值,单位为 KB。
➢ autoFlush:当输出缓冲区即将溢出时,是否需要强制输出缓冲区的内容。设置为 true 时为正常输出;如果设置为 false,则会在 buffer 溢出时产生一个异常。
➢ info:设置该 JSP 程序的信息,也可以看做其说明,可以通过 Servlet.getServletInfo()方法获取该值。如果在 JSP 页面中,可直接调用 getServletInfo()方法获取该值,因为 JSP 页面的实质就是 Servlet。
➢ errorPage:指定错误处理页面。如果本页面产生了异常或者错误,而该 JSP 页面没有对应的处理代码,则会自动调用该属性所指定的JSP页面。
➢ isErrorPage:设置本 JSP 页面是否为错误处理程序。如果该页面本身已是错误处理页面,则通常无须指定 errorPage 属性。
➢ contentType:用于设定生成网页的文件格式和编码字符集,即 MIME 类型和页面字符集类型,默认的 MIME 类型是 text/html;默认的字符集类型为 ISO-8859-1。
➢ pageEncoding:指定生成网页的编码字符集。
从JSP 的 4 种基本语法中执行数据库操作的 JSP 页面中可以看出,在basicSyntax\connDb.jsp 页面的头部,使用了两条 page 指令:
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ page import="java.sql.*" %>
其中第二条指令用于导入本页面中使用的类,如果没有通过 page 指令的 import 属性导入这些类,则需在脚本中使用全限定类名——即必须带包名。可见,此处的 import 属性类似于 Java 程序中的 import 关键字的作用。
如果删除第二条 page 指令,则执行效果如下图所示。
看下面的 JSP 页面,该页面使用 page 指令的 info 属性指定了 JSP 页面的描述信息,又使用 getServletInfo()方法输出该描述信息。
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!--指定info信息-->
<%@ page info="this is a jsp"%>
<!DOCTYPE html>
<html>
<head>
<title> 测试page指令的info属性 </title>
</head>
<body>
<!-- 输出info信息 -->
<%=getServletInfo() %>
</body>
<html>
以上页面的第 3 行代码设置了 info 属性,用于指定该 JSP 页面的描述信息;第 11 行代码使用了getServletInfo()方法来访问该描述信息。
在浏览器中执行该页面,将看到如下图所示的效果。
errorPage 属性的实质是 JSP 的异常处理机制,JSP 脚本不要求强制处理异常,即使该异常是checked异常。如果 JSP 页面在运行中抛出未处理的异常,系统将自动跳转到 errorPage 属性指定的页面;如果 errorPage 没有指定错误页面,系统则直接把异常信息呈现给客户端浏览器——这是所有的开发者都不愿意见到的场景。
看下面的 JSP 页面,该页面设置了 page 指令的 errorPage 属性,该属性指定了当本页面发生异常时的异常处理页面。
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="error.jsp" %>
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
</head>
<body>
<%
// 下面代码将出现运行时异常
int a = 6;
int b = 0;
int c = a / b;
%>
</body>
<html>
以上页面的 errorPage 属性指定 errorTest.jsp 页面(上面的页面)的错误处理页面是 error.jsp。下面是 error.jsp 页面,该页面本身是错误处理页面,因此将 isErrorPage 设置成true。
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<title> 错误提示页面 </title>
</head>
<body>
<!-- 提醒客户端系统出现异常 -->
系统出现异常<br/>
</body>
</html>
上面页面的 isErrorPage 属性指定error.jsp 页面是一个错误处理页面。在浏览器中浏览 errorTest.jsp 页面的效果如下图所示。
如果将前一个页面中 page 指令的 errorPage 属性删除,再次通过浏览器浏览该页面,执行效果如下图所示。
可见,使用 errorPage 属性控制异常处理的效果在表现形式上要好得多。
关于 JSP 异常,在介绍 exception 内置对象时还会有更进一步的解释。
include 指令
使用 include 指令,可以将一个外部文件嵌入到当前 JSP 文件中,同时解析这个页面中的 JSP 语句(如果有的话)。这是个静态的 inude 语句,它会把目标页面的其他编译指令也包含进来,但动态 include 则不会。
include 既可以包含静态的文本,也可以包含动态的 JSP 页面。静态的 include 编译指令会将被包含的页面加入本页面,融合成一个页面,因此被包含页面甚至不需要是一个完整的页面。
include 编译指令的语法如下:
<%@include file="relativeURISpec"%>
如果被嵌入的文件经常需要改变,建议使用<jsp:include>操作指令,因为它是动态的 include 语句。
下面的页面是使用静态导入的示例代码。
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<!DOCTYPE html>
<html>
<head>
<title> 静态include测试 </title>
</head>
<body>
<!-- 使用include编译指定导入页面 -->
<%@include file="scriptlet.jsp"%>
</body>
</html>
以上页面中第 9 行代码使用静态导入的语法将 scriptlet.jsp 页面导入本页,该页面的执行效果与 scriptlet.jsp 的执行效果相同。
查看 Tomcat 的 work\Catalina\localhost\directive\org\apache\jsp 路径下的 staticInclude_jsp.java文件,从 staticInclude.jsp 编译后的源代码可看到,staticInclude.jsp 页面已经完全将 scriptlet.jsp 的代码融入到本页面中。下面是 staticInclude_jsp.java 文件的片段:
out.write("<table bgcolor=\"#9999dd\" border=\"1\" width=\"300px\">\r\n");
out.write("<!-- Java脚本,这些脚本会对HTML的标签产生作用 -->\r\n");
for(int i = 0; i < 10; i++){
out.write("\r\n");
out.write(" <!-- 上面的循环将控制<tr>标签循环 -->\r\n");
out.write(" <tr>\r\n");
out.write(" <td>循环值:</td>\r\n");
out.write(" <td>");
out.print(i);
out.write("</td>\r\n");
out.write(" </tr>\r\n");
}
上面这些页面代码并不是由 staticInclude.jsp 页面所生成的,而是由 scriptlet.jsp 页面生成的。也就是说,scriptlet.jsp 页面的内容被完全融入 staticInclude.jsp 页面所生成的 Servlet 中,这就是静态包含意义:包含页面在编译时将完全包含了被包含页面的代码。
需要指出的是,静态包含还会将被包含页面的编译指令也包含进来,如果两个页面的编译指令冲突,那么页面就会出错。
评论