返回介绍

D.5 脚本元素

发布于 2025-04-22 20:10:07 字数 6528 浏览 0 评论 0 收藏

一个脚本程序是一个 java 代码块,以<%符号开始,以%>符号结束。以清单 D.6 的 scriptletTest.jsp 页面为例:

清单 D.6 使用脚本程序(scriptletTest.jsp)

< %@page import="java.util.Enumeration"%>
< !DOCTYPE html>
< html>
< head>< title>Scriptlet example< /title>< /head>
< body>
< b>Http headers:< /b>< br/>
< %-- first scriptlet --%>
<% for (Enumeration <String>e = request.getHeaderNames(); e.hasMoreElements(); ){ String header = e.nextElement(); out.println(header + ": " + request.getHeader(header) + "< br/>"); } String message = "Thank you."; %> < hr/> < %-- second scriptlet --%> < % out.println(message); %> < /body> < /html>

在上述清单 D.6 的 JSP 页面中,有两个脚本程序,需要注意的是定义在一个脚本程序中的变量可以被其后续的脚本程序使用。

脚本程序的第一行代码可以紧接<%标记,最后一行代码也可以紧接%>标记,不过,这会降低代码的可读性。

D.5.1 表达式

每个表达式都会被 JSP 容器执行,并使用隐式对象 out 的打印方法输出结果。表达式以“<%=”开始,并由“%>”结束。例如,在下面一行文本中,黑体字为一个表达式。

Today is < %=java.util.Calendar.getInstance().getTime() %>

注意,表达式无需分号结尾。

JSP 容器首先执行 java.util.Calendar.getInstance().getTime(),并将计算结果传递给 out.print(),这与如下脚本程序的效果一样:

Today is
<%
  out.print(java.util.Calendar.getInstance().getTime());
%>

D.5.2 声明

可以声明能在 JSP 页面中使用的变量和方法。声明以“<%!”开始,并以“%>”结束。例如,清单 D.7 的 declarationTest.jsp 页面展示了一个 JSP 页面,该页面声明了一个名为 getTodaysDate 的方法。

清单 D.7 使用声明(declarationTest.jsp)

<%!
  public String getTodaysDate() {
    return new java.util.Date();
  }
%>
<!DOCTYPE html>
<html>
<head><title>Declarations</title></head>
<body>
Today is <%=getTodaysDate()%>
</body>
</html>

在 JSP 页面中,一个声明可以出现在任何地方,并且一个页面可以有多个声明。

可以使用声明来重写 JSP 页面,实现类的 init 和 destroy 方法。通过声明 jspInit 方法,来重写 init 方法。通过声明 jspDestroy 方法,来重写 destory 方法。这两种方法说明如下。

  • jspInit。这种方法类似于 javax.servlet.Servlet 的 init 方法。JSP 页面在初始化时调用 jspInit。不同于 init 方法,jspInit 没有参数。还可以通过隐式对象 config 访问 ServletConfig 对象。

  • jspDestroy。这种方法类似于 Servlet 的 destroy 方法,在 JSP 页面将被销毁时调用。

清单 D.8 呈现的 lifeCycle.jsp 页面演示了如何重写 jspInit 和 jspDestroy。

清单 D.8 lifeCycle.jsp 页面

<%!
  public void jspInit() {
    System.out.println("jspInit ...");
  }
  public void jspDestroy() {
    System.out.println("jspDestroy ...");
  }
%>
<!DOCTYPE html>
<html>
<head><title>jspInit and jspDestroy</title></head>
<body>
Overriding jspInit and jspDestroy
</body>
</html>

lifeCycle.jsp 页面会被转换成如下的 Servlet:

package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class lifeCycle_jsp extends 
    org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  public void jspInit() {
    System.out.println("jspInit ...");
  }

  public void jspDestroy() {
    System.out.println("jspDestroy ...");
  }

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
      javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long>
    _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long>
      getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory =
        _jspxFactory.getJspApplicationContext(
        getServletConfig().getServletContext())
        .getExpressionFactory();
    _jsp_instancemanager =
        org.apache.jasper.runtime.InstanceManagerFactory
        .getInstanceManager(getServletConfig());
  }

  public void _jspDestroy() {
  }

  public void _jspService(final
      javax.servlet.http.HttpServletRequest request, final
      javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException,
      javax.servlet.ServletException {

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request,
        response, null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("<!DOCTYPE html>\n");
      out.write("<html>\n");
      out.write("<head><title>jspInit and jspDestroy" +
          "</title></head>\n");
      out.write("<body>\n");
      out.write("Overriding jspInit and jspDestroy\n");
      out.write("</body>\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof
          javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            out.clearBuffer();
          } catch (java.io.IOException e) {
          }
        if (_jspx_page_context != null)
          _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

注意生成的 Servlet 类中的 jspInit 和 jspDestroy 方法。

现在可以通过如下 URL 访问 lifeCycle.jsp:

http://localhost:8080/jspdemo/lifeCycle.jsp

第一次访问页面时,可以在控制台上看到“jspInit...”,并且在 Servlet/JSP 容器关闭时看到“jspDestory...”。

D.5.3 禁用脚本元素

随着 JSP 2.0 对表达式语言的加强,推荐的做法是:在 JSP 页面中用 EL 访问服务器端对象且不写 Java 代码。因此,从 JSP 2.0 起,可以通过在部署描述符中的<jsp-property-group>定义一个 scripting-invalid 元素,来禁用脚本元素。

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
    <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。