一、JSP基本语法
- JSP简介
- JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。
- JSP技术的特点:
JSP是一种服务器端脚本语言,其出现降低了Servlet编写页面的难度。
JSP本质上就是Servlet,实际上JSP是首先被翻译成Servlet后才编译运行的,因此JSP能够实现Servlet所能够实现的所有功能。
相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。
- 第一个JSP程序
一个显示当前服务器系统时间的JSP页面示例:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <font color="red"> <% java.util.Date date = new java.util.Date(); out.println("当前时间是:"+date.toLocaleString()); %> </font> </body> </html>
- JSP运行原理
- JSP执行过程可分为五个步骤,各步骤含义如下:
1.客户向服务器发送JSP页面请求(request);
2.容器接收到请求后检索对应的JSP页面,如果该JSP页面(或被修改后的JSP页面)是第一次被请求,则容器将此页面中的静态数据(HTML文本)和动态数据(Java脚本)全部转化成Java代码,使JSP文件翻译成一个Java文件,即Servlet;
3.容器将翻译后的Servlet源代码编译形成字节码文件(.class),对于Tomcat服务器而言,生成的字节码文件默认存放在“<Tomcat安装目录>\work目录下”;
4.编译后的字节码文件被加载到容器内存中执行,并根据用户的请求生成HTML格式的响应内容;
5.容器将响应内容即响应(response)发送回客户端。
- 当同一个JSP页面再次被请求时,只要该JSP文件没有发生过改动,容器将直接调用已装载的字节码文件,而不会再执行翻译和编译的过程,从而大大提高了服务器的性能。
- JSP页面基本结构
JSP页面由模板文本和JSP元素组成。
- 在一个JSP页面中,所有非JSP元素的内容称为模板文本(template text)。模板文本可以是任何文本,如:HTML、XML,甚至可以是纯文本。
JSP并不依赖于HTML,它可以采用任何一种标记语言。模板文本通常被直接传递给浏览器。在处理一个JSP页面请求时,模板文本和JSP元素所生成的内容会合并,合并后的结果将作为响应内容发送给浏览器。JSP有三种类型的元素:
脚本元素(scripting element)、指令元素(directive element)和动作元素(action element)。
脚本元素
允许用户将小段的Java代码添加到JSP页面中,脚本元素在页面被请求时执行。JSP脚本元素包括:脚本、表达式、声明和注释。
- JSP脚本
语法: <% Java代码 %>- JSP表达式
JSP中的表达式可以被看做一种简单的输出形式,需要注意的是,表达式一定要有一个可以输出的值。
语法: <%= 表达式 %>- JSP声明
JSP中的声明用于声明一个或多个变量和方法,并不输出任何的文本到输出流。在声明元素中声明的变量和方法将在JSP页面初始化时进行初始化。
语法 : <%! JSP声明 %>- JSP声明变量与普通脚本变量的区别:
声明变量将做为JSP翻译生成的Servlet的属性,所有对该JSP的请求将共享此变量;
普通脚本变量将做为JSP翻译生成的Servlet的_jspService()方法中的局部变量,每个对该JSP的请求将被分配给一个同名的此变量。
指令元素
JSP指令(directive)是为JSP引擎(Servlet容器)而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。
JSP指令的基本语法格式: <%@ 指令 属性名=“值” %>
如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。
JSP指令元素包括三种:page指令、include指令、taglib指令
- page指令
描述了和页面相关的信息,如:导入所需类包、指明输出内容类型、控制Session等。page指令一般位于JSP页面的开头部分,在一个JSP页面中,page指令可以出现多次,但是在每个page指令中,每一种属性却只能出现一次,重复的属性设置将覆盖掉先前的设置。- jsp文件编码问题:
pageEncoding: 告诉tomcat服务器使用什么编码翻译jsp文件(jsp->java文件)
contentType: tomcat服务器发送给浏览器的数据编码(tomcat服务器->浏览器)
异常错误相关的:
errorPage: 指定当前jsp页面的错误处理页面。
isErorrPage: 指定当前页面是否为错误处理页面。false,不是错误处理页面,则不能使用exception内置对象;true,是错误处理页面,可以使用exception内置对象。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" errorPage="errorPage.jsp"%> <%@ page import="java.util.Date,java.sql.Connection" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% //模拟异常 String str = null; str.toCharArray(); %> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <p>系统出现异常,系统管理员正在维护中......</p> <p>错误信息如下:</p> <p> <%=exception.getMessage()%> </p> </body> </html>
- include指令
include指令的作用是在页面翻译期间引入另一个文件,被包含的文件可以是JSP、HTML或文本文件。
语法:<%@include file="文件"%>
include指令会先将当前JSP和被包含的文件融合到一起形成一个Servlet再进行编译执行;因此包含文件时,必须保证新合并生成的文件符合JSP语法规则。例如,当前文件和被包含文件的不能同时定义同名的变量,否则当前文件将不能编译通过,会提示Duplicate local variable错误。- include指令引入一个JSP页面
<%@include file="header.jsp"%>
- taglib指令
taglib指令用于指定JSP页面所使用的标签库,通过该指令可以在JSP页面中使用标签库中的标签。
语法:
<%@taglib uri="标签库URI" prefix="标签前缀"%>
其中:
uri指定描述这个标签库位置的URI,可以是相对路径或绝对路径;
prefix指定使用标签库中标签的前缀。
对上述示例指定的标签库,可以使用如下代码进行标签的引用:
<c:out value="hello world"/>
其中“c”为标签的前缀,在JSP中有些前缀已经保留,如果自定义标签,这些标签前缀不可使用。保留前缀有:jsp、jspx、java、javax、servlet、sun和sunw。
动作元素(了解)
- 虽然JSP页面仅用作数据显示模块,希望不嵌套任何java业务逻辑代码,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面代码可维护性、可读性降低,因此Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码, 在jsp页面中也内置了一些标签(动作元素),开发人员使用这些标签可以完成页面的一些常用业务逻辑。
- JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能。
- JSP规范定义了一系列标准动作,常用有下列几种:
<jsp:include>标签
<jsp:forward>标签
<jsp:param>标签
- <jsp:include>标签
用于在页面运行时引入一个静态或动态的页面,也称为动态包含。
<jsp:include>如果包含的文件是普通的文本文件,就将文件的内容发送到客户端,由客户端负责显示;如果包含的文件是JSP文件,JSP容器就执行这个文件,然后将执行结果发送到客户端,由客户端负责显示这些结果。- 语法:
<jsp:include page=" relativeURL " flush="true|false" />
page指定引入文件的地址;
flush=“true”表示设定是否自动刷新缓冲区,默认为false,可省略;在页面包含大量数据时,为缩短客户端延迟,可将一部分内容先行输出;
<jsp:include>动作可以包含一个或几个<jsp:param>子动作,用于向要引入的页面传递数据。<jsp:include page=" relativeURL " flush="true|false" > <jsp:param name="name" value="value"/> ...... </jsp:include>
- include指令元素与include动作元素
共同点:include指令元素和include动作元素的作用都是实现包含文件代码的复用。
区别:对包含文件的处理方式和处理时间不同。
include指令元素是在翻译阶段就引入所包含的文件,被处理的文件在逻辑和语法上依赖于当前JSP页面,其优点是页面的执行速度快。
include动作元素是在JSP页面运行时才引入包含文件所产生的应答文本,被包含的文件在逻辑和语法上独立于当前JSP页面,其优点是可以使用param子元素更加灵活地处理所需要的文件,缺点是执行速度要慢一些。
- <jsp:forward>标签
<jsp:forward>标签用于把请求转发给另外一个资源。
<jsp:forward>可以包含一个或几个<jsp:param>子动作,用于向所转向的页面传递参数。<jsp:forward page=“url"> <jsp:param name="name" value="value"/> ...... </jsp:forward>
二、JSP内置对象
- JSP内置对象是指在JSP页面中,不用声明就可以在脚本和表达式中直接使用的对象。JSP内置对象也称隐含对象。
- JSP内置对象有如下特点:
内置对象由Web容器自动载入,不需要实例化;
内置对象通过Web容器来实现和管理;
在所有的JSP页面中,直接调用内置对象都是合法的。
每个JSP 页面在第一次被访问时,JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用。
由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的_jspService时,会传递或创建9个与web开发相关的对象供_jspService使用。
- out对象
out对象即输出对象,用来控制管理输出的缓冲区(buffer)和输出流(output stream)向客户端页面输出数据。
向out对象的输出流中写入数据时,数据会先被存储在缓冲区中,在JSP默认配置下,缓冲区满时会被自动刷新输出。
- request对象、response对象
- request对象
request对象即请求对象,表示客户端对服务器发送的请求,主要用于接受客户端通过HTTP协议传送给服务器端的数据。与Servlet中的请求对象为同一对象。request对象的作用域为一次request请求。- response对象
response对象即响应对象,表示服务器对客户端的响应。主要用来将JSP处理后的结果传回到客户端。与Servlet中的响应对象为同一对象。
- session对象、application对象
- session对象
即会话对象,表示浏览器与服务器之间的一次会话,具体工作原理与使用方法与Servlet中一致。
通常只应该把与用户会话状态相关的信息放入session范围内;不要仅仅为了两个页面之间传递信息就将信息放入session范围,这样会加大服务器端的开销;如果仅仅是为了两个页面交换信息,应将该信息放入request范围内,然后通过请求转发即可。- application对象:
即应用程序上下文对象,表示当前应用程序运行环境,用以获取应用程序上下文环境中的信息,application对象在容器启动时实例化,在容器关闭时销毁。作用域为整个Web容器的生命周期。具体工作原理与使用方法与Servlet中一致。
- pageContext对象
- pageContext即页面上下文对象,表示当前页面运行环境,用以获取当前JSP页面的相关信息。
pageContext对象作用范围为当前JSP页面。
pageContext对象可以访问当前JSP页面所有的内置对象。- 存取域属性的方法setAttribute()中scope参数被定义为四个常量,分别代表四种作用域范围:
PAGE_SCOPE = 1代表page范围;
REQUEST_SCOPE = 2代表request范围;
SESSION_SCOPE = 3代表session范围;
APPLICATION_SCOPE = 4代表application 范围。session.setAttribute("a","hello"); pageContext.setAttribute("a",pageContext.SESSION_SCOPE); session.getAttribute("a","hello"); pageContext.getAttribute("a",pageContext.SESSION_SCOPE);
- JSP的四种作用域(重点)
对象的生命周期和可访问性称为作用域(scope)
- 在JSP中有四种作用域:
pageContext page域
request request域
session session域
application context域- 域对象作用:保存数据和获取数据 ,用于数据共享。
- 域对象方法:
setAttribute("name",Object) 保存数据
getAttribute("name") 获取数据
removeAttribute("name") 清除数据
四种作用域的生命周期和可访问性如下:
- 页面域(page scope),存储在页面域的对象只对于它所在页面是可访问的。
- 请求域(request scope),请求域的生命周期是指一次请求过程,包括请求被转发(forward)或者被包含(include)的情况。存储在请求域中的对象只有在此次请求过程中才可以被访问。
- 会话域(session scope),会话域的生命周期是指某个客户端与服务器所连接的时间,存储在会话域中的对象在整个会话期间(可能包含多次请求)都可以被访问。
- 应用域(application scope),应用域的生命周期是指从服务器开始执行服务到服务器关闭为止,是四个作用域中时间最长的。存储在应用域中的对象在整个应用程序运行期间可以被所有JSP和Servlet共享访问,在使用时要特别注意存储数据的大小和安全性,否则可能会造成服务器负载过重和线程安全性问题。
<body> <% int pageCount = 1; int sessionCount = 1; int applicationCount = 1; //页面域计数 if (pageContext.getAttribute("pageCount") != null) { pageCount = Integer.parseInt(pageContext.getAttribute( "pageCount").toString()); pageCount++; } pageContext.setAttribute("pageCount", pageCount); //会话域计数 if (session.getAttribute("sessionCount") != null) { sessionCount = Integer.parseInt(session.getAttribute( "sessionCount").toString()); sessionCount++; } session.setAttribute("sessionCount", sessionCount); //应用域计数 if (application.getAttribute("applicationCount") != null) { applicationCount = Integer.parseInt(application.getAttribute( "applicationCount").toString()); applicationCount++; } application.setAttribute("applicationCount", applicationCount); %> <p> 页面域计数:<%=pageCount%></p> <p> 会话域计数:<%=sessionCount%></p> <p> 应用域计数:<%=applicationCount%></p> </body>
- config对象、page对象(了解即可)
- config对象
即页面配置对象,表示当前JSP页面翻译后的Servlet的ServletConfig对象,存放着一些初始的数据结构。- page对象
即this,代表JSP本身,更准确地说它代表JSP被翻译后的Servlet,因此它可以调用Servlet类所定义的方法。
config对象和page对象一样都很少被用到
- Exception对象
即异常对象,表示JSP页面产生的异常。
如果一个JSP页面要应用此对象,必须将此页面中page指令的isErrorPage属性值设为true,否则无法编译。
JSP最佳实践
JSP与Servlet,虽然都可以用于开发动态web资源,但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用,各取所长。
Servlet技术: 开发动态资源。是一个java类,最擅长写java代码
jsp技术: 开发动态资源。通过java代码最擅长输出html代码。
- servlet+jsp模式:
servlet:
(1)接收参数
(2)处理业务逻辑
(3)把结果保存到域对象中
(4)跳转到jsp页面
Jsp:
(1)从域对象取出数据
(2)把数据显示到浏览器