JSP

JSP（全称Jakarta Server Pages，曾称为JavaServer Pages）是由升阳电脑公司主导建立的一种动态网页技术标准。JSP部署于网络服务器上，可以响应客户端发送的请求，并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页，然后返回给请求者。JSP技术以Java语言作为脚本语言，为用户的HTTP请求提供服务，并能与服务器上的其它Java程序共同处理复杂的业务需求。
JSP将Java程序码和特定变动内容嵌入到静态的页面中，实现以静态页面为模板，动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签，用来调用内建功能。另外，可以创建JSP标签库，然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能，而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet程序码。JSP编译器可以把JSP文件编译成用Java程序码写的Servlet，然后再由Java编译器来编译成能快速执行的二进制机器码，也可以直接编译成二进制码。
综述.
JSP从2.0版本开始，增加了表达式语言（EL），以提供更快更简单的创建新标签的方法，并允许开发者创建Velocity式模板。如旧版本代码“codice_1”可简化为“codice_2。
包含内容.
JSP指令.
JSP指令控制JSP编译器如何去生成servlet，以下是可用的指令：
&lt;%@ include file="somefile.jsp" %&gt;
&lt;%@ page import="java.util.*" %&gt; //example import导入样例
&lt;%@ page contentType="text/html" %&gt; //example contentType页面类型样例
&lt;%@ page isErrorPage=false %&gt; //example for non error page无错误页面样例
&lt;%@ page isThreadSafe=true %&gt; //example for a thread safe JSP执行序安全JSP样例
注意：在同一个JSP文件中只有“import”导入页面指令可以被多次使用。
&lt;%@ taglib prefix="myprefix" uri="taglib/mytag.tld" %&gt;
JSP脚本元素和变量.
标准脚本变量.
以下是永远可用的脚本变量：
脚本元素.
有三个基本的脚本元素，作用是使JAVA代码可以直接插入servlet.
JSP动作.
JSP动作是一系列可以调用内建于网络服务器中的功能的XML标签。JSP提供了以下动作：
标签样例.
jsp:include.
&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
&lt;jsp:include page="mycommon.jsp" &gt;
 &lt;jsp:param name="extraparam" value="myvalue" /&gt;
&lt;/jsp:include&gt;
name:&lt;%=request.getParameter("extraparam")%&gt;
&lt;/body&gt;
&lt;/html&gt;
jsp:forward.
&lt;jsp:forward page="subpage.jsp" &gt;
 &lt;jsp:param name="forwardedFrom" value="this.jsp" /&gt;
&lt;/jsp:forward&gt;
在本例中，请求被传递到"subpage.jsp"，而且请求的处理权不会再返回前者。
jsp:useBean.
&lt;jsp:useBean id="myBean" class="com.foo.MyBean" scope="request" /&gt;
&lt;jsp:getProperty name="myBean" property="lastChanged" /&gt;
&lt;jsp:setProperty name="myBean" property="lastChanged" value="&lt;%= new Date()%&gt;" /&gt;
scope属性可以是request, page, session or application，它有以下用意：
上述例子将会用一个创建一个类的实例，并且把该实例存储在属性中，该属性将在该请求的生命周期内有效。它可以在所有被包含或者从主页面（最先接收请求的页面）转向到的JSP页之间共享。
JSP标签库.
除了JSP预定义动作之外，开发者还可以使用JSP标签扩展API添加他们自定义的"动作"。开发者写一种实现一个标签的界面和一个标签库的XML描述文件的JAVA类，这就能指定标签和实现标签的JAVA类
请看如下JSP：
&lt;%@ taglib uri="mytaglib.tld" prefix="myprefix" %&gt;
&lt;myprefix:myaction&gt; &lt;%-- the start tag %&gt;
&lt;/myprefix:myaction&gt; &lt;%-- the end tag %&gt;
JSP编译器将会载入mytaglib.tld这个XML文件，然后可以看到标签"myaction"由JAVA类"MyActionTag"实现。当该标签首次在文件中使用时，将会创建一个MyActionTag的实例。然后（而且当每次该标签被使用时），当出现开始标签时，将会调用doStartTag()方法，根据开始标签的结果，来决定如何处理标签的主体。主体是指开始标签和结束标签之间的文本。这个doStartTag()方法将会返回如下之一：
当结束标签出现时，它会调用doEndTag()方法，该方法会返回如下两做之一：
上述myaction标签tag会有一个类似下面例子的用于实现的类：
public class MyActionTag extends TagSupport {
 //Releases all instance variables.
 //called for the start tag
 //called at the end tag
本地化.
JSP的本地化是通过和JAVA应用程序相同的方式完成的，即使用资源包。
模型-视图-控制器 模式.
为了把表现层（presentation）从请求处理（request processing）和数据存储（data storage）中分离开来（这样更利于开发、查错和功能扩展），升阳公司推荐在JSP文件中使用一种称作模型-视图-控制器（MVC）的架构模式。按照此设计，当用户访问网站上的特定网址时，用户的处理请求会先由网站服务器获取到，然后先交由网站的控制器程序作初步处理。用户的访问请求可能多种多样，比如查询信息或进行数据计算都是常见的网站业务。控制器程序会初步判断用户请求的种类，然后把用户请求转发给与特定业务对应的Servlet程序或者另一个独立的JSP文件进行业务处理。当请求处理完后，再通过一个专门负责输出信息的JSP页以清晰、美观的方式向用户的浏览器输出结果。简而言之，先由控制器拦截用户请求并做初步判断，再由业务处理程序访问数据（从数据库中访问）和处理业务，最后由视图组件生成结果页面并发送结果给用户。其中JSP一般用作展示输出结果，可以用于展示经Servlet查询或处理后的结果；也可以用一个JSP文件处理业务逻辑，再用另一个JSP文件展示结果。按功能做这样的文件拆分（而非由一个臃肿的JSP页面包揽所有功能）是为了便于团队分工。MVC本身是一种由来已久的设计思想，基于JSP的技术只是实现MVC架构的流行方案之一。Struts和Spring框架等好几种流行的网站建设框架都是基于MVC模式设计的。
JSP和Servlets.
从架构上说，JSP可以被看作是从Servlets高级提炼而作为Java Servlet 2.1 API的扩展而应用。Servlets和JSP最早都是由升阳电脑开发的。从JSP1.2版本以来，JSP处于JCP开发模式下。JSR-53规定了JSP 1.2和Servlet 2.4的规范，JSR-152规定了JSP 2.0的规范。2006年5月，JSP 2.1的规范作为Java EE 5的一部份，在JSR-245中发布。
静态数据在输入文件中的内容和输出给HTTP响应的内容完全一致。此时，该JSP输入文件会是一个没有内嵌JAVA或动作的HTML页面。而且，客户端每次请求都会得到相同的响应内容。
样例.
不管JSP编译器是生成SERVLET的JAVA源码，或者是直接发布二进制码，了解一下JSP编译器是如何把文件转换成一个JAVA SERVLET，都是很有帮助的。例如，看一下如下输入JSP和它最后生成的JAVA SERVLET：
输入JSP
&lt;%@ page errorPage="myerror.jsp" %&gt;
&lt;%@ page import="com.foo.bar" %&gt;
&lt;html&gt;
&lt;head&gt;
&lt;%! int serverInstanceVariable = 1;%&gt;
&lt;% int localStackBasedVariable = 1; %&gt;
&lt;table&gt;
 &lt;tr&gt;&lt;td&gt;&lt;%= "expanded inline data " + 1 %&gt;&lt;/td&gt;&lt;/tr&gt;
最后生成的JAVA 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 &lt;%@ page import="com.foo.bar" %&gt;
import ...
class _myserlvet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {
 //inserted as a
 //result of &lt;%! int serverInstanceVariable = 1;%&gt;
 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( "&lt;html&gt;\r\n" );
 out.print( "&lt;head&gt;\r\n" );
 //from &lt;% int localStackBasedVariable = 1; %&gt;
 int localStackBasedVariable = 1;
 out.print( "&lt;table&gt;\r\n" );
 out.print( " &lt;tr&gt;&lt;td&gt;" );
 //note, toStringOrBlank() converts the expression into a string or if
 // the expression is null, it uses the empty string.
 //from &lt;%= "expanded inline data " + 1 %&gt;
 out.print( toStringOrBlank( "expanded inline data " + 1 ) );
 out.print( " &lt;/td&gt;&lt;/tr&gt;\r\n" );
 } catch ( Exception _exception ) {
 //clean up and redirect to error page in &lt;%@ page errorPage="myerror.jsp" %&gt;