ITEEDU

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>