3.1、JSP概述

Jsp页面实在jsp容器中执行的。Servlet容器一般也是JSP容器。比如,Tomcat就是一个Servlet/JSP容器。

第一次请求一个jsp页面时,Servlet/JSP容器要做两件事情:

1、将JSP页面转换成一个JSP页面实现类,这是一个实现javax.servlet.jsp.JspPage接口或其子接口javax.servlet.jsp.HttpjspPage的java类,JspPage是javax.servlet.Servlet的子接口,这样就会使每一个jsp页面都成为一个Servlet。

2、假设转换成功,Servlet/JSP容器将会编译Servlet类。

 

3.2、备注

Jsp页面能够使用两种备注:

1、jsp备注。说明该页面的作用

2、HTML/XHTML备注。这些将被发送到浏览器。

JSP备注以<%--开头,以--%>结束。比如,以下就是一个JSP备注:

<%-- retrieve products to display --%>

JSP备注不会被发送到浏览器,也不能进行嵌套。

HTML/XHTML备注不是由容器进行处理,而是被发送到浏览器。HTML/XHTML备注的用途之中的一个是标识JSP页面:

<!-- this is /jsp/store/displayProducts.jspf -->

在处理带有很多JSP片段的应用程序时,这个特别实用。开发人员通过查看浏览器的HTML源码,能够轻松查出某个HTML代码部分生成了哪个JSP页面或者哪个片段。

 

3.3、隐式对象

Jsp中存在9个隐式对象:request、response、out、session、application、config、pageContext、page、Exception。

 

3.4、指令

指令是第一种jsp句法元素,其指示jsp转换器应该怎样将某个jsp页面转换成Servlet的命令。最重要的是这两个:page和include。

 

3.4.1、page指令

Page指令的语法例如以下:

<%@ page attrubute1=”value1” attribute=”value2” ...%>

@和page之间的空格是可选的,attribute1、attribute2等都是page指令的属性。以下是page指令的属性列表:

import。指定要导入的一种或多种java类型,供本页的java代码所用。比如:import=”java.util.List”。

session。值为true时,表示这个页面參与session管理;值为false时,表示不參与session管理。默认值为true,意味着假设之前还没有javax.servlet.http.HttpSession实例,那么调用JSP页面将始终会创建一个。

buffer。指定隐式对象out的缓冲区大小,以千字节为单位。

autoFlush。默认值为true,表示当缓冲区满时,杯缓存的输出应该自己主动刷新。值为false时,表示仅仅有在调用隐式对象response的flush方法时,才进行刷新缓冲区。因此,当缓冲区溢出时会抛出一个异常。

 

isThreadSafe。表示页面中实现的线程安全级别。建议JSP的作者不要使用这个属性,由于它会产生一个包涵不建议使用的代码的Servlet。

Info。指定所生成Servlet的getServletInfo方法返回值。

errorPage、表示负责处理该页面可能出现的错误的页面。

isErrorPage。表明这个页面是否负责处理错误。

contentType。指定该页面隐式对象response的内容类型,其默认值为text/html。

pageEncoding。指定该页面的字符编码,其默认值为ISO-8859-1.

isELIgnored。表名是否忽略EL表达式。EL是Expression Language的缩写。

Language。指定该页面使用的脚本语言,其默认值为java。

Extends。指定这个JSP页面的实现类必须扩展的超类。该属性非常少使用,使用时应该特别小心。

deferredSyntaxAllowedAsLiteral。指明是否同意用字符序列#{做为该页面和编译单元的String字面值,其默认值为false。#{非常重要,由于它在EL表达式中是一个特殊的字符序列。

trimDirectiveWhitespaces。表明是否从输出内容中删除仅仅包括空格的模版文本,其默认值为false,也就是说,不删除空格。

Page指令也能够多次出现。可是,在多个page指令中多次出现的同一个属性,它的值必须一致,仅仅有import属性例外。放在多个page指令中的import属性,其效果能够累积。比如,以下的page指令将会同一时候导入java.util.ArrayList和java.io.File

<% @page import=”java.util.ArrayList”%>

<% @page import=”java.io.File”%>

其结果与以下的这行代码同样:

<% @page import=”java.util.ArrayList, java.util.Date”%>

以下再举个样例。这个page指令将session属性值设为false,并将页面的缓冲区容量设为16kb

<% @page session=”false” buffer=”16kb”%>

 

3.4.2、include指令

Include指令的语法例如以下:

<%@ include file=”url”%>

此处@和include之间的空格是可选的,而且url是表示一个include文件的相对路径,假设url以一个正斜线(/)开头,那么其在server中就会杯解读成是一条绝对路径。假设不是以正斜线开头,则被解读为是相对于当前JSP页面的路径。

依照规范,include文件的扩展名应为jspf,表示为JSP fragment。现在。JSP fragment也称作JSP segmen,仅仅是为了保持一致,仍然用jspf做为扩展名。

 

3.5、脚本元素

另外一种JSP句法元素是脚本元素,它将java代码合并成一个JSP页面。脚本元素有3种类型:Scriplet、声明及表达式。

 

3.5.1、Scriptlet

Scriptlet是一个java代码块,它以<%开头,以%>结束。

 

3.5.2、表达式

表达式的运算结果会杯填入隐式对象out的print方法中。表达式以<%开头,并以%>结束。比如,以下就是一个表达式:

Today is <%=java.util.Calendar.getInstance().getTime()%>

注意:表达式后面不须要用分号。

这个表达式和以下的Scriplet是一样的

<%

Out.print(java.util.Calendar.getInstance().getTime()) ;
%>

 

3.5.3、声明

声明可以在JSP页面中使用变量和方法。声明要用<%!和%>包起来。以下就声明了一个方法。

<%!

public String getTodaysDate(){

return new java.util.Date() ;

}

%>

声明能够放在jsp页面中的不论什么位置,而且同一个页面中能够有多个声明。

我们能够利用声明覆盖实现类中的init和destroy方法。覆盖init,要声明一个jspInit方法;覆盖destroy,要声明一个jspDestroy方法。比如:

<%!

Public void jspInit(){

System.out.println(“jspInit...”) ;

}

Public void jspDestroy(){

System.out.println(“jspDestroy...”) ;

}

%>

 

3.5.4、关闭脚本元素

随着jsp2.0中EL的发展,建议做法是利用EL来訪问server的对象,而不是在JSP页面中编写java代码。为此,原本开启的jsp2.0脚本元素,能够通过在部署描写叙述符的<jsp-property-group>中定义一个scripting-invalid元素,将它关闭,例如以下所看到的:

<jsp-property-group>

<url-pattern>*.jsp</url-pattern>

<scripting-invalid>true</scripting-invalid>

</jsp-property-group>

 

3.6、动作

3.6.1、useBean

这个动作将创建一个与某个java对象相关的脚本变量。它将是表现逻辑与业务逻辑切割开来最easy的方法之中的一个。可是有了像定制标签和EL这类技术之后,如今已经非常少使用useBean了。

<jsp:useBean id=”today” class=”java.util.Date”/>

 

3.6.2、setProperty和getProperty

<jsp:useBean id=”employee” class=”app03a.Employee”/>

<jsp:setProperty name=”employee” property=”fitstName” value=”Abigail”>

First Name:<jsp:getProperty name=”employee” property=”firstName”/>

 

3.6.3、include

Include动作用于动态地包括还有一个资源,它能够包括还有一个jsp页面、一个Servlet或者一个静态的HTML页面。

<jsp:include page=”jspf/menu.jsp”>

</jsp:include>

理解include指令和include动作之间的差别是非常重要的。使用include指令时,这样的包括是发生在页面转换的时候,比如jsp容器将页面转换成一个生成的Servlet的时候。使用include动作时,这样的包括则是发生在请求的时候。因此,能够利用include动作传递參数,而不是利用include指令。

第二个差别在于,使用include指令时,杯包括资源的文件扩展名并不重要。而使用include动作时,文件扩展名则必须为jsp,以便它可以做为一个jsp页面进行处理。比如,在include动作中用jspf做为扩展名时,将会使得这个jsp segment被当作静态文件进行处理。

 

3.6.4、forward

Forward动作是将当前页面跳转到还有一个不同的资源。比如,以下的forward动作就是将当前页面跳转到login.jsp页面。

<jsp:forward page=”jspf/login.jsp”>

</jsp:forward>

 

3.6.5、错误处理

在jsp中错误处理支持得非常好。你能够利用try语句处理java代码,也能够指定一个页面,让他在应用程序遇到未捕捉的异常时显示出来,那么,一旦发生异常,用户将会看到一张经过精心设计的页面,解释眼下发生了什么状况,而不是用一条错误消息打发用户,让他们皱眉不已。

利用page指令的isErrorPage属性,就能够把一个jsp页面变成一个错误处理页面,该属性必须为true。以下是一个错误处理程序。

buggy.jsp

<%@ page errorPage="errorHandler.jsp"%>
    <%
    	Integer.parseInt("ee");
    %>
errorHandler.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%>
<html>
  <head>
  	<title>Error</title>
  </head>
  
  <body>
    An error has occurred.<br/>
    Error message:
    <%
    	out.println(exception.toString()) ;
    %>
  </body>
</html>
假设执行这个buggy.jsp页面,它就会抛出一个异常。但你不会看到Servlet/JSP容器产生的错误消息,而是会看到errorHandler.jsp页面显示的内容。

 

3.7、小结

 

Jsp实在java中构建web应用程序的另外一种技术,作为servlet技术的补充,而不是要代替他。设计得好的java web应用程序一般都会用到servlet和jsp。