JSP

一、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页面中,所有非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)把数据显示到浏览器
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,406评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,976评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,302评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,366评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,372评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,457评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,872评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,521评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,717评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,523评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,590评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,299评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,859评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,883评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,127评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,760评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,290评论 2 342

推荐阅读更多精彩内容