大可制作:QQ群:31564239(asp|jsp|php|mysql)

JSP/Servlet: Scripting Elements

您使用<% 与 %>来包括JSP网页中动态的部份,在当中撰写Java程序码,这是JSP的Scripting Elements之一,Scripting Elements共有三个:Scriptlet、Declaration与Expression。
  1. Scriptlet:以<% 与 %>包括的元素
  2. Declaration:以<%! 与 %>包括的元素
  3. Expression:以<%= 与 %>包括的元素

以<% 与 %>包括的部份可以包括Java程序语法,您可以将程序逻辑分作数个段,例如:
<%
    String c = request.getParameter("condition");
    if(c != null && c.equals("show")) {
%>
    <h1>Message 1 shown</h1>
<%
    } else {
%>
    <h1>Message 1 not shown</h1>
<%
    }
%>
 
request是JSP的隐含对象,转换为Servlet之后对应于 javax.servlet.http.HttpServletRequest对象,您可以从request中得到客户端相关的请求信息,例如使用request的getParameter("condition")就可以取得客户端 请求中所设定的"condition"参数,假设文件储存为conditionTest.jsp,使用 http://localhost:8080/myjsp/conditionTest.jsp?condition=show,则网页上会显示:
Message 1 shown

如果没有设定任何的参数,则会显示:
Message 1 not shown

在转换为Servlet之后,由<% 与 %>包括的部份主要集合为一个_jspService()方法,例如上面的Scriptlet会转换为:
public void _jspService(HttpServletRequest request,
                         HttpServletResponse response)
        throws java.io.IOException, ServletException {
    ....
    String c = request.getParameter("condition");
    if(c != null && c.equals("show")) {
      out.write("\n");
      out.write("    <h1>Message 1 shown</h1>\n");
    } else {
      out.write("\n");
      out.write("    <h1>Message 1 not shown</h1>\n");
    }
    ....
}
 
注意到在JSP中<% 与 %>间声明的变量,其转换为方法中的一个区域变量,这可以与<%!与%>间声明的变量相比较,JSP网页最后会转译为一个Servlet类,如果您在JSP中使用<%!与%>来声明一个变量,则它在Servlet中会对应至一个field成员,例如:
<%!
    String str1;
    int i, j;
%>
 
<%
    str1 = "This is a test!";
    i = 10;
    j = 20;
%>
 

这个简单的程序在转换为Servlet之后,主要对应的部份如下:
public final class Test_jsp
    extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {
    .....
    String str1;
    int i, j;
 
    ....
    public void _jspService(HttpServletRequest request,
                            HttpServletResponse response)
        throws java.io.IOException, ServletException {
 
        str1 = "This is a test!";
        i = 10;
        j = 20;
    }
}
 

由于Servlet被载入后,将会一直存在于JVM中,直到容器规定的存在期限过期,或是关闭服务器后才会清除Servlet产生的实例,所以使用<%!与% >声明变量时,必须小心数据共用与线程安全的问题,默认上容器会使用同一个Servlet实例来服务来自不同使用者的请求,而 <%!与%>间声明的变量对应至field成员,所以对于同一个实例来说,如果某个请求已设定了str1,而另一个请求要求显示str1,则 第二个请求有可能显示的会是第一个请求所设定的值,因而使得显示的请求不正确。

并不是要求不要在<%!与%>间声明变量,只要了解其实际对应产生的是Servlet类中的一个field,而且默认上容器会使用同一个实 例来服务来自不同使用者的请求,视需求使用即可,不过建议学习过Java Thread的人来使用,因为会比较了解数据共用、线程安全等问题与解决方法。
<%!与%>之间也可以声明method,例如:
<%!
    private String sayHelloto(String name) {
         return "Hello, " + name;
    }
%>
 

这个method可以在同一个JSP页面中调用,而它将在转换为Servlet之后,成为Servlet类的一个method member,您可以自己试着看看产生之后的Servlet程序码。

<%= expression %>是一个运算式表示,它可以视作 <% out.println(expression); %> 的一个简单表示法,其中expression是一个运算表示式,例如:<% out.println(new java.util.Date()); %>就可以写成<%= new java.util.Date() %>,注意这个表示法中最后不需要加上分号,例如这样就是错的语法:
<%= new java.util.Date(); %>


对于Web应用程序来说,Scriptlet是个不乐意被见到的东西,因为它会使得HTML与Java程序码交相混杂,对于程序的维护来说相当的麻烦,必 要的时候,您可以在web.xml中加上<script-invalid>标签,设定所有的JSP网页都不可以使用Scriptlet,例 如:
...
<web-app ..>
    ....
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <script-invalid>true</script-invalid>
        </jsp-property-group>
    </jsp-config>
....
</web-app>