3.4 JSP动作

上一节介绍了JSP的page、include、taglib这3个指令,这些指令不仅可以帮助JSP编程人员编写出复杂的JSP页面,而且能简化JSP页面代码,为后期维护带来便利。本节介绍JSP中另外一组元素:JSP动作。在JSP中一共有13个动作:<jsp:include>、<jsp:forward>、<jsp:plugin>、<jsp:param>、<jsp:useBean>、<jsp:getProperty>、<jsp:setProperty>、<jsp:output>、<jsp:attribute>、<jsp:element>、<jsp:body>、<jsp:params>、<jsp:fallback>。其中<jsp:include>和<jsp:forward>用的比较多,<jsp:useBean>、<jsp:getProperty>和<jsp:setProperty>与JavaBean相互结合,将在第8章详细介绍。本节先介绍其他的JSP动作。

3.4.1 <jsp:include>动作

<jsp:include>动作与include指令十分相似,它们的作用都是引入文件到目标页面。<jsp:include>语法格式如下:

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

例如:

      <jsp:include page="top.html" flush="true"/>

其中page属性是<jsp:include>动作的一个必选属性,它指明了需要包含文件的路径,该路径可以是相对的也可以是绝对的。flush属性用于指定输出缓存是否转移到被导入文件中。如果指定为true,则包含在被导入文件中;如果指定为false,则包含在原文件中。

提示

page属性所指的绝对路径不是文件系统的绝对路径,而是以应用系统目录为根目录的绝对路径。通常Web应用下的WEB-INF目录就是根目录。一般在设定URL时指定相对路径,这样简单些。

使用<jsp:include>动作与include指令可以达到相同的界面效果。例如上节中介绍的使用include指令演示界面页脚的例子,直接将include替换成<jsp:include>动作,它们在页面显示结果中没有什么不同。

使用jsp:include包含页脚信息的代码如下:

      ----------------- index_include.jsp ----------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      03   <html>
      04       <head>
      05        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
      06        <title>JSP include动作演示</title>
      07       </head>
      08       <body>
      09           <jsp:include page="john.html" />
      10           <br/>
      11          <div align="center">JSP include指令演示</div>
      12           <jsp:include  page="copyRight.jsp"  flush="true"/>
      13       </body>
      14   </html>

上述示例中,代码第9行换成jsp:include动作。可以看出,两种不同的包含方式达到了相同的效果。

但是,jsp:include动作与include指令还是有些不同的。首先,jsp:include动作是在页面被访问时导入的,而include指令是有JSP引擎编译时导入的;其次,include指令中,被包含的文件会同主页面一块被编译为一个Servlet类文件,而jsp:include动作包含的文件和主页面会是相对独立的两个文件,在编译时会被编译成两个Servlet类文件。因此jsp:include在效率上稍微慢些。

【例3.5】演示jsp:include动作。

    ----------------- news.jsp ----------------
    01   <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    02   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    03   <html>
    04    <head>
    05      <title>新闻摘要</title>
    06       <meta http-equiv="pragma" content="no-cache">
    07       <meta http-equiv="cache-control" content="no-cache">
    08       <meta http-equiv="expires" content="0">
    09       <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
    10       <meta http-equiv="description" content="This is my page">
    11    </head>
    12    <body>
    13        <center>
    14           <table>
    15               <tr>
    16                 <th>中华新闻网</th>
    17               </tr>
    18           </table>
    19        </center>
    20       <p>最新新闻摘要:
    21          <ul>
    22              <li><jsp:include page="news1.html" /></li>
    23              <li><jsp:include page="news3.html"/></li>
    24              <li><jsp:include page="news3.html"/></li>
    25          </ul>
    26        </p>
    27    </body>
    28   </html>

上述代码中,代码第22~24行使用JSP动作,页面运行效果如图3.5所示。

图3.5 jsp:include运行结果

3.4.2 <jsp:forward>动作

<jsp:forward>动作的作用是转发请求到另外一个页面中,在请求过程中会连同请求的参数数据一起被转发到目标页面中,目标页面通过request.getParameter方法获得参数值进行进一步处理。<jsp:forward>基本语法如下:

      <jsp:forward page="relative URL">

<jsp:forward>只有page一个属性,其值为相对的URL。例如:

      <jsp:forward page="/error.jsp"/>

将跳转到错误页面。

来看一个<jsp:forward>的例子。如果随机数能被2整除,则跳转到even.jsp,否则跳转到odd.jsp。

【例3.6】演示jsp:forward动作。

      ----------------------- forwardE.jsp--------------------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
      02   <%
      03       String url = "";
      04      int random = (int)(Math.random()*10); //产生10以内的随机数
      05       int m = random%2;
      06       switch(m){
      07           case 0:
      08              url = "even.jsp";
      09              break;
      10           case 1:
      11              url = "odd.jsp";
      12              break;
      13       }
      14   %>
      15   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      16   <html>
      17    <head>
      18      <title>My JSP 'forwardE.jsp' starting page</title>
      19       <meta http-equiv="pragma" content="no-cache">
      20       <meta http-equiv="cache-control" content="no-cache">
      21       <meta http-equiv="expires" content="0">
      22       <meta http-equiv="keywords" content="keyword1, keyword2, keyword3">
      23       <meta http-equiv="description" content="This is my page">
      24    </head>
      25
      26    <body>
      27        <jsp:forward page="<%=url %>"/>
      28    </body>
      29   </html>

上述代码中,代码第2~14行使用Java判断url的返回值,其中even.jsp中的内容为“能被2整除,跳转到偶数页界面”, odd.jsp中的内容为“不能被2整除,跳转到奇数页界面”,本例效果如图3.6所示。

图3.6 jsp:forward运行结果

从上述代码的运行结果看出,界面已经被重定向到odd.jsp页面,但是浏览器中的地址仍显示的是跳转前的地址。这也算是<jsp:forward>动作的一个特点,相对于请求者而言,所看出的响应仍然是原先请求的页面给出的,请求者并不会获得转发后的页面地址。这样相对来说,请求具有隐蔽性。

提示

<jsp:forward>动作中的url页面只能是该Web应用中的文件,不能是该Web应用之外的文件。

3.4.3 <jsp:param>动作

<jsp:param>用来传递参数信息,它经常与其他动作一起使用,比如与<jsp:forward>、<jsp:include>等结合使用传递主页面的参数到目标页面。其基本语法如下:

      <jsp:param name=" 参数名称" value=" 参数值">

例如:

      <jsp:param name="username" value="李四">

【例3.7】和【例3.8】分别是<jsp:param>和<jsp:include>、<jsp:forward>结合使用的例子,由主页面和子页面构成。子页面从主页面中获得参数值显示。

【例3.7】演示<jsp:param>和<jsp:include>结合使用。

      ----------------------- main.jsp--------------------------
      01   <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
      02  <%request.setCharacterEncoding("utf-8"); //设定页面传递参数的编码格式%>
      03   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      04   <html>
      05    <head>
      06     <title>主页面</title>
      07    </head>
      08
      09    <body>
      10        <center>
      11           <table>
      12               <tr>
      13                 <th>主页面</th>
      14               </tr>
      15           </table>
      16        </center>
      17        <jsp:include page="subPage.jsp" >
      18            <jsp:param value="John" name="userName"/>
      19            <jsp:param value="10086" name="passwd"/>
      20           <jsp:param value="北京丰台" name="address"/>
      21        </jsp:include>
      22    </body>
      23   </html>

上述代码中,第17行引用<jsp:include>动作,代码第18~20行使用<jsp:param>参数。

    ----------------------- subPage.jsp--------------------------
    01   <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    02   <%
    03      String userName= request.getParameter("userName");
    04      String passwd= request.getParameter("passwd");
    05      String address= request.getParameter("address");
    06      System.out.println(address);
    07   %>
    08   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    09   <html>
    10    <head>
    11      <title>子页面</title>
    12    </head>
    13    <body>
    14        <center>
    15           <table>
    16               <tr>
    17                 <th>子页面:人员信息</th>
    18               </tr>
    19           </table>
    20        </center>
    21        <center>
    22           <table>
    23                <tr>
    24                 <td>用户名:<%=userName%></td>
    25                </tr>
    26                <tr>
    27                 <td>密 码:<%=passwd%></td>
    28                </tr>
    29                <tr>
    30                 <td>用户地址:<%=address%></td>
    31                </tr>
    32           </table>
    33        </center>
    34    </body>
    35   </html>

上述代码中,第22~32行获取主页面传递的参数值。

提示

所有的页面编码格式要统一,否则在传递中文时会出现乱码问题。request.setCharacterEncoding方法是设定传递参数的编码格式,在传递中文时要特别注意。在URL中包含参数传递时,可能会有中文乱码或者特殊字符问题,需要对这些参数进行编码处理。在JavaScript(简称JS)中,通过调用函数encodeURI或者encodeURIComponent实现编码,在JSP脚本中,通过方法URLEncoder.encode实现转码。

页面效果如图3.7所示。

图3.7 <jsp:param>和<jsp:include>结合使用运行结果

【例3.8】演示<jsp:param>和<jsp:forward>结合使用。

    ----------------------- main.jsp--------------------------
    01   <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    02  <%request.setCharacterEncoding("utf-8"); //设定页面传递参数的编码格式%>
    03   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    04   <html>
    05    <head>
    06     <title>主页面</title>
    07    </head>
    08
    09    <body>
    10        <center>
    11           <table>
    12               <tr>
    13                 <th>主页面</th>
    14               </tr>
    15           </table>
    16        </center>
    17        <jsp:forward page="subPage.jsp" >
    18            <jsp:param value="Smith" name="userName"/>
    19            <jsp:param value="10086" name="passwd"/>
    20           <jsp:param value="北京丰台" name="address"/>
    21        </jsp:forward>
    22    </body>
    23   </html>

上述代码中,第2行设置请求编码,第17行使用<jsp:forward>动作,第18~20行使用<jsp:param>参数

      ----------------------- subPage.jsp--------------------------
      01  <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>○3
      02   <%
      03      String userName= request.getParameter("userName");
      04      String passwd= request.getParameter("passwd");
      05      String address= request.getParameter("address");
      06      System.out.println(address);
      07   %>
      08   <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      09   <html>
      10    <head>
      11      <title>子页面</title>
      12    </head>
      13    <body>
      14        <center>
      15           <table>
      16               <tr>
      17                 <th>子页面:人员信息</th>
      18               </tr>
      19           </table>
      20        </center>
      21        <center>
      22           <table>
      23                <tr>
      24                 <td>用户名:<%=userName%></td>
      25                </tr>
      26                <tr>
      27                 <td>密 码:<%=passwd%></td>
      28                </tr>
      29                <tr>
      30                 <td>用户地址:<%=address%></td>
      31                </tr>
      32           </table>
      33        </center>
      34    </body>
      35   </html>

上述代码中,第2~7行代码获取主页面传递的参数值,第22~30行显示获取的参数值,页面效果如图3.8所示。

图3.8 <jsp:param>与<jsp:forward>结合使用运行结果

从上述例子可以看出,<jsp:param>在<jsp:include>、<jsp:forward>中的用法基本一样,只是将<jsp:include>替换成<jsp:forward>动作就可以。