JSP

来自ITwiki,开放的信息技术大百科

JSP(全称JavaServer Pages)是由Sun Microsystems公司倡导和许多公司参与共同建立的一种使软件开发者可以响应客户端请求,而动态生成HTML、XML或其它格式文档的Web网页的技术标准。JSP技术是以Java语言作为脚本语言的,JSP网页为整个服务器端的Java库单元提供了一个接口来服务于HTTP的应用程序。

JSP使Java代码和特定的预定义动作可以嵌入到静态页面中。JSP句法增加了被称为JSP动作的XML标签,它们用来调用内建功能。另外,可以创建JSP标签库,然后象使用标准HTML或XML标签一样使用它们。标签库提供了一种和平台无关的扩展服务器性能的方法。

JSP被JSP编译器编译成Java Servlets。一个JSP编译器可以把JSP编译成JAVA代码写的servlet然后再由JAVA编译器来编译成机器码,也可以直接编译成二进制码。

目录 [隐藏] 1 JSP 和 Servlets 2 JSP 句法 2.1 静态数据 2.2 JSP 指令 2.3 JSP脚本元素和变量 2.3.1 标准脚本变量 2.3.2 脚本元素 2.4 JSP 动作 2.4.1 标签样例 2.4.1.1 jsp:include 2.4.1.2 jsp:forward 2.4.1.3 jsp:plugin 2.4.1.4 jsp:useBean 2.5 JSP标签库 3 本地化 4 JSP 2.0 5 模-视图-控件 模式 6 样例 7 出版物 8 参见 9 外部链接


JSP 和 Servlets 从架构上说,JSP可以被看作是从servlets高级提炼而作为Servlet2.1 API的扩展而应用。Servlets和JSPs最早都是由Sun Microsystems(升阳公司)开发的。从JSP1.2版本以来,JSP处于Java Community Process开发模式下。JSR 53规定了JSP 1.2 和 Servlet 2.4的规范,JSR 152 规定了 JSP 2.0的规范。2006年5月,JSP 2.1的规范作为Java EE 5的一部份,在JSR245中发布。

JSP 句法 一个JSP页面可以被分为以下几部份:

静态数据,如 HTML JSP 指令,如 include 指令 JSP 脚本元素和变量 JSP 动作 用户自定义标签 静态数据 静态数据在输入文件中的内容和输出给HTTP 响应的内容完全一致。此时,该JSP输入文件会是一个没有内嵌JAVA或动作的HTML页面。而且,客户端每次请求都会得到相同的响应内容。

JSP 指令 JSP指令控制JSP编译器如何去生成 servlet,以下是可用的指令:

包含指令include – 包含指令通知JSP编译器把另外一个文件完全包含入当前文件中。效果就好象被包含文件的内容直接被粘贴到当前文件中一样。这个功能和C preprocessor所提供的很类似。被包含文件的扩展名一般都是 "jspf" (即 JSP Fragment,JSP碎片): <%@ include file="somefile.jsp" %> 页面指令page – 页面指令有以下几个选项:

import 使一个JAVA导入声明被插入到最终页面文件。 

contentType 规定了生成内容的类型。当生成非HTML内容或者当前字符集character set并非默认字符集时使用。 errorPage 处理HTTP请求时,如果出现异常则显示该错误提示信息页面。 isErrorPage 如果设置为TRUE,则表示当前文件是一个错误提示页面。 isThreadSafe 表示最终生成的servlet 是否安全线程( thread safe)。 </table>


<%@ page import="java.util.*" %> //example import导入样例 <%@ page contentType="text/html" %> //example contentType页面类型样例 <%@ page isErrorPage=false %> //example for non error page无错页面样例 <%@ page isThreadSafe=true %> //example for a thread safe JSP安全线程JSP样例会 注意: 在同一个JSP文件中只有"import"导入页面指令可以被多次使用。

标签库指令taglib – 标签库指令描述了要使用的JSP标签库。该指令需要指定一个前缀prefix(和C++的命名空间很类似)和标签库的描述URI: <%@ taglib prefix="myprefix" uri="taglib/mytag.tld" %> JSP脚本元素和变量 标准脚本变量 以下是永远可用的脚本变量:

out – JSPWriter用来写入响应流的数据 page – servlet自身 pageContext – 一个 PageContext 实例包括和整个页面相联系的数据,一个给定的HTML页面可以在多个JSP之间传递。 request – HTTP request 对象 response – HTTP response 对象 session – HTTP session 对象,在多个请求之间追踪一个客户的信息。 脚本元素 有三个基本的脚本元素,作用是使JAVA代码可以直接插入 servlet.

一种是声明标签,在JAVA SERVLET的类体中放入一个变量的定义。静态的数据成员也可以如此定义。 <%! int serverInstanceVariable = 1; %> 一种是脚本标签,在JAVA SERVLET的类的_jspService()方法中放入所包含的语句。 <% int localStackBasedVariable = 1; out.println(localStackBasedVariable); %> 一种是表达式标签,在JAVA SERVLET的类中放入待赋值的表达式,表达式注意不能以分号结尾。 <%= "expanded inline data " + 1 %> JSP 动作 JSP动作是一系列可以调用内建于网络服务器中的功能的XML标签。JSP提供了以下动作:

jsp:include 和子过程类似,JAVA SERVLET暂时接管对其它指定的JSP页的请求和响应。当处理完该JSP页后就马上把控制权交还当前JSP页。这样JSP代码就可以在多个JSP页中共享而不用复制。 

jsp:param 可以在jsp:include, jsp:forward 或 jsp:params块之间使用。指定一个将加入请求的当前参数组中的参数。 jsp:forward 用于处理对另一个JSP或SERVLET的请求和响应。控制权永远不会交还给当前JSP页。 jsp:plugin Netscape Navigator 的老版本和 Internet Explorer 使用不同的标签以嵌入一个applet。这个动作产生为嵌入一个APPLET所需要的指定浏览器标签。 jsp:fallback 如果浏览器不支持APPLETS则会显示的内容。 jsp:getProperty 从指定的JavaBean。 jsp:setProperty 在指定的JavaBean中设置一个属性值。 jsp:useBean 创建或者复用一个JavaBean 变量到JSP页。


标签样例 jsp:include <html> <head></head> <body> <jsp:include page="mycommon.jsp" >

   <jsp:param name="extraparam" value="myvalue" />

</jsp:include> name:<%=request.getParameter("extraparam")%> </body></html> jsp:forward <jsp:forward page="subpage.jsp" >

   <jsp:param name="forwardedFrom" value="this.jsp" />

</jsp:forward> 在本例中,请求被传递到"subpage.jsp",而且请求的处理权不会再返回前者。

jsp:plugin <jsp:plugin type=applet height="100%" width="100%"

           archive="myjarfile.jar,myotherjar.jar"
           codebase="/applets"
           code="com.foo.MyApplet" >
   <jsp:params>
       <jsp:param name="enableDebug" value="true" />
   </jsp:params>
   <jsp:fallback>
       Your browser does not support applets.
   </jsp:fallback>

</jsp:plugin> 上述 plugin 例子说明了一种在网页中嵌入applet的统一方法。在<OBJECT>标签出现之前,并没有一种嵌入applets的通用方法。这个标签设计得并不好,但有希望在以后加入动态属性(height="${param.height}", code="${chart}"等)和动态参数的新功能。 目前jsp:plugin标签不允许动态调用 applets。例如,你如果有一个图表applet需要数据点以参数形式被传入,除非数据点的数量是一个常量,否则你就不能使用ResultSet 循环来创建jsp:param标签,你不得不手写每个jsp:param标签的代码。而每个上述jsp:param标签可以有一个动态命名和动态值。

jsp:useBean <jsp:useBean id="myBean" class="com.foo.MyBean" scope="request" /> <jsp:getProperty name="myBean" property="lastChanged" /> <jsp:setProperty name="myBean" property="lastChanged" value="<%= new Date()%>" /> scope属性可以是 request, page, session or application,它有以下用意:

request — 该属性在请求的生命周期内有效,一旦请求被所有的JSP页处理完后,那么该属性就不可引用。 page — 该属性只是当前页中有效。 session — 该属性在用户会话的生命周期内有效。 application — 该属性在各种情况下都有效,并且永远不会被变为不可引用,和侨居变量global variable相同。 上述例子将会用一个创建一个类的实例,并且把该实例存储在属性中,该属性将在该请求的生命周期内有效。它可以在所有被包含或者从主页面(最先接收请求的页面)转向到的JSP页之间共享。

JSP标签库 除了JSP预定义动作之外,开发者还可以使用JSP标签扩展API添加他们自定义的动作。开发者写一种实现一个标签的界面和一个标签库的XML描述文件的JAVA类,这就能指定标签和实现标签的JAVA类请看如下JSP:

<%@ taglib uri="mytaglib.tld" prefix="myprefix" %>

...

<myprefix:myaction> <%-- the start tag %>

...

</myprefix:myaction> <%-- the end tag %> ... JSP编译器将会载入mytaglib.tld这个XML文件,然后可以看到标签myaction由JAVA类MyActionTag实现。当该标签首次在文件中使用时,将会创建一个MyActionTag的实例。然后(而且当每次该标签被使用时),当出现开始标签时,将会调用doStartTag()方法,根据开始标签的结果,来决定如何处理标签的主体。主体是指开始标签和结束标签之间的文本。这个doStartTag()方法将会返回如下之一:

SKIP_BODY - 标签之间不做处理。 EVAL_BODY_INCLUDE - 对标签之内主体进行赋值。 EVAL_BODY_TAG - 对标签之内主体进行赋值并把结果输出到流(保存在标签的主体内容属性中)。 注意: 如果标签扩展了 BodyTagSupport 类,当主体被执行时会在调用doEndTag()之前调用doAfterBody()方法。该方法用于实现循环结构。 当结束标签出现时,它会调用doEndTag()方法,该方法会返回如下两做之一:

EVAL_PAGE - 表示JSP文件的剩余部份将会被执行。this indicates that the rest of the JSP file should be processed. SKIP_PAGE - 表示将不会再有更多执行操作。当前JSP页交出控制权。就象在转发动作中的作用一样。 上述 myaction 标签tag 会有一个类似下面例子的用于实现的类:

public class MyActionTag extends TagSupport {

   //Releases all instance variables.
   public void release() {...}
   public MyActionTag() { ... }
   //called for the start tag
   public int doStartTag() { ... }
   //called at the end tag   

} Add Body Tag description.

本地化 JSP的本地化Internationalization 是通过和JAVA应用程序相同的方式完成的,即使用 resource bundle.

JSP 2.0 新的JSP规范版本包括新的用于提升程序员工作效率功能,主要有:

An Expression Language (EL) 允许开发者创建 Velocity-样式 templates (among other things). 更快更简单的创建新标签的方法。 Hello, ${param.visitor} <%-- same as: Hello, <%=request.getParameter("visitor")%> --%> 模-视图-控件 模式 为了把表现层presentation从请求处理request processing 和数据存储data storage中分离开来,升阳公司推荐在JSP文件中使用一种模-视图-控件Model-view-controller 模式。 规范的SERVLET或者分离的JSP文件用于处理请求。当请求处理完后,控制权交给一个只作为创建输出作用的JSP页。有几种平台都基于服务于网络层的模-视图-控件 模式(比如Struts 和Spring framework)。



样例 不管JSP编译器是生成SERVLET的JAVA源码,或者是直接发布二进制码,了解一下JSP编译器是如何把文件转换成一个JAVA SERVLET,都是很有帮助的。例如,看一下如下输入JSP和它最后生成的JAVA SERVLET:

Input JSP

<%@ page errorPage="myerror.jsp" %>
<%@ page import="com.foo.bar" %>
<html>
<head>
<%! int serverInstanceVariable = 1;%>
...
<% int localStackBasedVariable = 1; %>
...

Resulting servlet

package jsp_servlet;
import java.util.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import com.foo.bar; //imported as a result of <%@ page import="com.foo.bar" %>
import ...
class _myserlvet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {
    //inserted as a
    //result of <%! int serverInstanceVariable = 1;%>
    int serverInstanceVariable = 1; 
    ...
    public void _jspService( javax.servlet.http.HttpServletRequest request,
                             javax.servlet.http.HttpServletResponse response )
      throws javax.servlet.ServletException,
             java.io.IOException
    {
        javax.servlet.ServletConfig config = ...;//get the servlet config
        Object page = this;
        PageContext pageContext = ...;//get the page context for this request 
        javax.servlet.jsp.JspWriter out = pageContext.getOut();
        HttpSession session = request.getSession( true );
        try {
            out.print( "<html>\r\n" );
            out.print( "<head>\r\n" );
            ...
            //from <% int localStackBasedVariable = 1; %>
            int localStackBasedVariable = 1; 
            ...
out.print( "
<%= "expanded inline data " + 1 %>
\r\n" ); out.print( " \r\n" ); ... } catch ( Exception _exception ) { //clean up and redirect to error page in <%@ page errorPage="myerror.jsp" %> } } } 出版物 JavaServer Pages, Third Edition, Hans Bergsten, O'Reilly & Associates, Inc., Sebastopol, California, 2003. ISBN 0-596-00563-6 参见 JSTL Java EE JavaServer Faces Java Servlet SSJS WAR (file format) EAR (file format) JAR (file format) Apache Tomcat 外部链接 Sun's JSP product description JSR 245 (JSP 2.1) JSR 152 (JSP 2.0) JSR 53 (JSP 1.2) Free JSP training/learning materials 网页技术与标准编辑 W3C标准: CSS | HTML | XHTML | XML 动态页面技术: ASP | ActiveX | ColdFusion | Flash | Java | JSP | PHP | AJAX | XMLHTTP .NET技术: ASP.NET | C# | J# | VB.NET 脚本编程语言: ActionScript(flash) | JavaScript | JScript | VBScript | ECMAScript
" );
            //note, toStringOrBlank() converts the expression into a string or if
            // the expression is null, it uses the empty string.
            //from <%= "expanded inline data " + 1 %>
            out.print( toStringOrBlank( "expanded inline data " + 1 ) );
out.print( "