Servlet和JSP之有关Servlet和JSP的梳理(二)
JSP
JSP页面本质上是一个Servlet,JSP页面在JSP容器中运行,一个Servlet容器通常也是JSP容器。
当一个JSP页面第一次被请求时,Servlet/JSP容器主要做一下两件事情:
① 转换JSP页面到JSP页面实现类,该实现类是一个实现javax.servlet.jsp.JspPage接口或子接口javax.servlet.jsp.HttpJspPage的Java类。该实现类的类名由Servlet/JSP容器生成。如果出现转换错误,则相关错误信息将被发送到客户端。
② 如果转换成功,Servlet/JSP容器随后编译该Servlet类,并装载和实例化该类,想其他正常的Servlet一样执行生命周期操作。
用一张图来描述以上操作,如下:

对于同一个JSP页面的后续请求,Servlet/JSP容器会先检查JSP页面是否被修改过。如果是,则该JSP页面会被重新翻译、编译并执行。如果不是,则执行已经在内存中的JSP Servlet。这样一来,一个JSP页面的第一次调用的实际花费总比后来的花费多,因为它涉及翻译和编译。为了解决这个问题,可以执行下列动作:
① 配置应用程序,使所有的JSP页面在应用程序启动时被调用,而不是在第一次请求时被调用。
② 预编译JSP页面,并将其部署为Servlet。
JSP自带的API包含4个包:
|
包 |
说明 |
|
javax.servlet.jsp |
包含用于Servlet/JSP容器将JSP页面翻译为Servlet的核心类和接口。 |
|
javax.servlet.jsp.tagext |
包括用于开发自定义标签的类型。 |
|
javax.el |
提供了统一表达式语言的API。 |
|
javax.servlet.jsp.el |
提供了一组必须由Servlet/JSP容器支持,以便在JSP页面中使用表达式语言的类。 |
JSP支持两种不同的注释格式:
|
注释类型 |
格式 |
特点 |
|
JSP注释 |
<%-- …… --%> |
JSP注释不会被发送到浏览器端,也不会被嵌套 |
|
HTML/XHTML注释 |
<!-- …… --> |
一个HTML/XHTML注释不会被容器处理,会原样发送给浏览器。HTML/XHTML主食的一个用途是用来确定JSP页面本身。 |
JSP九大隐式(内置)对象:
|
对象 |
类型 |
说明 |
|
request |
javax.servlet.http.HttpServletRequest |
每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的reuqest对象来代表这个请求。request对象提供了一系列方法来获取HTTP头信息、cookies、HTTP方法等等。 |
|
response |
javax.servlet.http.HtpServletResponse |
当服务器创建request对象时会同时创建用于响应这个客户端的response对象。response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies、时间戳、HTTP状态码等等。 |
|
out |
javax.servlet.jsp.JspWriter |
out对象用来在response对象中写入内容。 |
|
session |
javax.servlet.http.HttpSession |
session对象用来跟踪在各个客户端请求间的会话。 |
|
application |
javax.servlet.ServletContext |
application对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestory()的调用而被移除。通过向application中添加属性,则所有组成web应用的JSP文件都能访问到这些属性。 |
|
config |
javax.servelt.ServletConfig |
config对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。 |
|
pageContext |
javax.servlet.jsp.PageContext |
pageContext对象主要用来访问页面信息,同时过滤大部分实现细节。该对象除了pageContext、page、exception对象的属性不能导出,其余内置对象的属性都能导出,而且该对象包含了传给JSP页面的指令信息,也定义了一些字段。 |
|
page |
javax.servlet.jsp.HttpJspPage |
page对象就是页面实例的引用,可以被看做是整个JSP页面的代表(与this对象同义) |
|
exception |
java.lang.Throwable |
exception对象包装了从先前页面中抛出的异常信息,通常被用来产生对出错条件的适当响应。 |
指令
指令是JSP语法元素的第一种类型。它们指示JSP转换器如何翻译JSP页面为Servlet。
page指令
可以使用page指令来控制JSP转换器转换当前JSP页面的某些方面。
page指令的语法如下:
<%@ page attribute1="value1" attribute2="value2" ...%>
以下是page指令属性的列表:
|
属性 |
描述 |
|
import |
定义一个或多个本页面中将被导入和使用的java类型。 |
|
session |
默认值为True,本页面加入会话管理;值为false则相反 |
|
buffer |
以KB为单位,定义隐式对象out的缓冲大小。必须以KB后缀结尾,默认为8KB或更大。该值可以为none,这意味着没有缓冲,所有数据将直接写入PrintWriter。 |
|
autoFlush |
默认值为True。若值为True,则当输出缓冲满时会自动写入输出流。而值为False,则仅当调用隐式对象的flush方法时,才会写入输出流。因此,若缓冲溢出则会抛出异常。 |
|
isThreadSafe |
定义该页面的线程安全级别。 |
|
info |
返回调用容器生成的Servlet类的getServletInfo方法的结果。 |
|
errorPage |
定义当出错时用来处理错误的页面。 |
|
isErrorPage |
标识本页是一个错误处理页面。 |
|
contentType |
定义本页面隐式对象response的内容类型,默认是text/html。 |
|
pageEncoding |
定义本页面的字符编码。 |
|
isELIgnored |
配置是否忽略EL表达式。 |
|
language |
定义本页面的脚本语言类型。 |
|
extends |
定义JSP实现类要继承的父类。 |
|
deferredSyntaxAllowedAsLiteral |
定义是否解析字符串中出现”#{“符号,默认是False。”{#”是一个表达式语言的启示符号。 |
|
trimDirectiveWhitespaces |
定义是否不输出多余的空格/空号,默认是False。 |
大部分page指令可以出现在页面的任何位置,但一般page指令是放在第一行代码的位置。page指令也可以出现多次,但出现多次的指令属性必须具有相同的值。不过,import属性例外,多个包含import属性的page指令的结果是累加的。
include指令
可以使用include指令将其他文件中的内容包含到当前JSP页面。一个页面中可以有多个include指令。若存在一个内容会在多个不同页面中使用或一个页面不同位置使用的场景,则将该内容模块化include文件非常有用。
include指令的语法如下:
<%@ include file="url" %>
JSP指令有很多,但是其中page和include指令最为重要,其余的taglib、tag、attribute以及variable指令会在后文出现。
脚本元素
一个脚本程序是一个Java代码块,以<%符号开始,以%>符号结束。
|
脚本元素类型 |
描述 |
格式 |
|
表达式 |
每个表达式都会被JSP容器执行,并使用隐式对象out的打印方法输出结果。 |
表达式以”<%=”开始,并以”%>”结束。表达式无需分号结尾。 |
|
声明 |
可以声明能在JSP页面中使用的变量和方法。可以使用声明来冲希望JSP页面,实现类的init和destory方法。 |
声明以”<%!”开始,并以”%>”结束。 |
|
禁用脚本元素 |
在JSP页面中用EL访问服务器端对象而不写Java代码。 |
可以通过在部署描述符中的<jsp-property-group>定义一个scripting-invalid元素,来禁用脚本元素。 <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> |
动作
动作是第三种类型的语法元素,他们被转换成Java代码来执行操作,如访问一个Java对象或调用方法。
|
动作 |
说明 |
|
useBean |
useBean将创建一个关联Java对象的脚本变量。 |
|
setProperty |
setProperty动作可以对一个Java对象设置属性 |
|
getProperty |
getProperty动作会输出Java对象的一个属性。 |
|
include |
include动作用来动态地引入另一个资源。可以引入另一个JSP页面,也可以引入一个Servlet或一个静态的HTML页面。而且使用include动作可以传递参数。 |
|
forward |
forward将当前页面转向到其他资源。 |
错误处理
JSP提供了很好的错误处理能力。除了在Java代码中可以使用try语句,还可以指定一个特殊页面。当应用页面遇到未捕获的异常时,用户将看到一个精心设计的页面解释发生了什么,而不是一个用户无法理解的错误信息。可以使用page指令的isErrorPage属性(属性值必须为True)来标识一个JSP页面是错误页面。
EL表达式
表达式语言的语法
EL表达式以${开头,并以}结束。EL表达式的结构如下:
${expression}
它也常用来连接两个表达式。对于一系列的表达式,它们的取值将是从左到右进行,计算结果的类型是String,并且连接在一起。如果在定制标签的属性值中使用EL表达式,那么该表达式的取值结果字符串将会是强制变成该属性需要的类型:
<my:tag somAttribute="${expression}"/>
像${这样的字符顺序就表示是一个EL表达式的开头,如果需要的只是文本${,则需要在它前面加一个转义符,如\${。
关键字
以下是关键字,他们不能用作标识符:and eq gt true instanceof or ne le false empty not lt ge null div mod 。
[]和.运算符
EL表达式可以返回任意类型的值。如果EL表达式的结果是一个带有属性的对象,则可以利用[]或者.运算符来访问该属性。"[]"和"."运算符类似;"[]"是比较规范的形式,"."运算符是比较便捷的方式,不过如果该变量名(如下的propertyName)不是有效的Java变量名,那只能有用"[]"运算符。如下例子:
${object["propertyName"]}
${object.propertyName}
取值规则
EL表达式的取值是从左到右进行的。对于expr-a[expr-b]形式的表达式,其EL表达式的取值方法如下:
(1)先计算expr-a得到value-a。
(2)如果value-a为null,则返回null。
(3)然后计算expr-b得到value-b。
(4)如果value-b为null,则返回null。
(5)如果value-a为java.util.Map,则会查看value-b是否为Map中的一个key。若是,则返回value-a.get(value-b),若不是,则返回null。
(6)如果value-a为java.util.List,或者加入它是一个array,则要进行一下处理:
a.强制value-b为int,如果强制失败,则抛出异常。
b.如果value-a.get(value-b)抛出IndexOutOfBoundsException,或者加入Array.get(value-a, value-b)抛出ArrayIndexOutOfBoundsException,则返回null。
c.否则,若value-a是一个List,则返回value-a,get(value-b);若value-a是一个array,则返回Array.get(value-a, value-b)。
(7)如果value-a不是一个Map、List或者array,那么,value-a必须是一个JavaBean。在这种情况下,必须强制value-b位String。如果value-b是value-a的一个可读属性,则要调用该属性的getter方法,从中返回值。如果getter方法抛出异常,该表达式就是无效的,否则,该表达式有效。
访问JavaBean
利用"."或者"[]"运算符,都可以访问bean的属性,其结构如下:
${beanName["propertyName"]}
${beanName.propertyName}
EL隐式对象
|
对象 |
描述 |
|
pageContent |
这是当前JSP的javax.servlet.jsp.PageContent。 |
|
initParam |
这是一个包含所有环境初始化参数,并用参数名作为key的Map。 |
|
param |
这是一个包含所有请求参数,并用参数名作为key的Map。每个key的值就是指定名称的第一个参数值。因此,如果两个请求参数同名,则只有第一个能够利用param获取值。要想访问同名参数的所有参数值,就得用params代替。 |
|
paramValues |
这是一个包含所有请求参数,并用参数名作为key的Map。每个key的值就是一个字符串数组,其中包含了指定参数名称的所有参数值。就算该参数只有一个值,它也仍然会返回一个带有一个元素的数组。 |
|
header |
这是一个包含请求标题,并用标题名作为key的Map。每个key的值就是指定标题名称的第一个标题,换句话说,如果一个标题的值不止一个,则只返回第一个值。要想获得多个值的标题,得用headerValues对象代替。 |
|
headerValues |
这是一个包含请求标题,并用标题名作为key的Map。每个key的值就是一个字符串数组,其中包含了指定标题名称的所有参数值。就算该标题只有一个值,它也仍然会返回一个带有一个元素的数组。 |
|
cookie |
这是一个包含了当前请求对象中所有Cookie对象的Map。Cookie名称就是key名称,并且每个key都映射到一个Cookie对象。 |
|
applicationScope |
这是一个包含了ServletContext对象中所有属性的Map,并用属性名称作为key。 |
|
sessionScope |
这是一个包含了HttpSession对象中所有属性的Map,并用属性名称作为key。 |
|
requestScope |
这是一个Map,其中包含了当前HttpServletRequest对象中的所有属性,并用属性名称作为key。 |
|
pageScope |
这是一个Map,其中包含了全页面范围内的所有属性。属性名称就是Map的key。 |
使用其他EL运算符
①算术运算符:加法(+)、减法(-)、乘法(*)、除法(/和div)、取余/取模(%和mod)。
②逻辑运算符:和(&&和and)、或(||和or)、非(!和not)。
③关系运算符: 等于(==和eq)、不等于(!=和ne)、大于(>和gt)、大于或等于(>=和ge)、小于(<和lt)、小于或等于(<=和le)。
④empty运算符:empty运算符用来检查某一个值是否为null或者empty。如:
${empty X}
如果X为null,或者说X是一个长度为0的字符串,那么该表达式将返回True。如果是一个空Map、空数组或者空集合,它也将返回True。否则,将返回False。
EL变量
|
JSP内置对象 |
EL名称 |
|
Page |
PageScope |
|
Request |
RequestScope |
|
Session |
SessionScope |
|
Application |
ApplicationScope |
如果EL变量没有做范围的限定,那么系统会默认以PageScope---->RequestScope----->SessionScope----->ApplicationScope的顺序寻找变量。
如果这四个范围都没有找到变量,那么系统会默认输出””空的字符串。
EL自动类型转换
要取得文本框中的输入,我们需要做类型转换,如:
String str_count = request.getParameter(“count”); int count = Integer.parseInt(str_count); count = count+20;
EL会进行自动类型转换,只需要这么写:
${param.count+20}
Servlet和JSP之有关Servlet和JSP的梳理(二)的更多相关文章
- 初识Jsp,JavaBean,Servlet以及一个简单mvc模式的登录界面
1:JSP JSP的基本语法:指令标识page,include,taglib;page指令标识常用的属性包含Language用来定义要使用的脚本语言:contentType定义JSP字符的编码和页面响 ...
- JSP/SERVLET入门教程--Servlet 使用入门
现在的JSP书籍有的是直接讲述JSP的使用,然后再讲解SERVERLET的使用;也有书籍是先讲述SERVERLET的使用,然后讲解JSP使用.个人认为第二种相对好一些,至于原因大家可以在学习体会到!所 ...
- 自建目录中jsp页面访问servlet路径出错404
---恢复内容开始--- 自建目录中jsp页面访问servlet路径出错404 使用eclipse建立的项目,总是会遇到路径问题,比如jsp页面访问servlet,jsp在默认的路径.jsp在自建目录 ...
- JSP lifecycle - with servlet
编译阶段: servlet容器编译servlet源文件,生成servlet类 初始化阶段: 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法 执行阶段: 调用与JSP对应的serv ...
- jsp请求由servlet响应的方式
一.登录页面主要代码:login.jsp<%@ page language="java" import="java.util.*" pageEncodin ...
- 学生管理系统开发代码分析笔记:jsp+java bean+servlet技术
1 序言 学习java web的时候很渴望有一份完整的项目给我阅读,而网上的大部分项目拿过来都无法直接用,好不容易找到了一个学生管理系统也是漏洞百出.在此,我将边修改边学习这份代码,并且加上完全的注释 ...
- JSP入门3 Servlet
需要继承类HttpServlet 服务器在获得请求的时候会先根据jsp页面生成一个java文件,然后使用jdk的编译器将此文件编译,最后运行得到的class文件处理用户的请求返回响应.如果再有请求访问 ...
- JSP编译成Servlet(四)JSP与Java行关系映射
我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...
- JSP编译成Servlet(三)JSP编译后的Servlet
JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什 ...
- JSP编译成Servlet(一)语法树的生成——语法解析
一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述.同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语 ...
随机推荐
- python常用第三方库(转载)
Python标准库与第三方库详解(转载) 转载地址: http://www.codeweblog.com/python%e6%a0%87%e5%87%86%e5%ba%93%e4%b8%8e%e7%a ...
- Tomcat自定义classLoader加密解密
class很好反编译,所以需要对class文件先进行加密,然后使用自己的classloader进行解密并加载. [步骤] 大概分两步: 1.对class文件进行加密 2.写解密class文件并加载的c ...
- TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)
12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...
- python3 类 组合
解决类与类之间代码冗余问题有两种解决方案: 第一 是继承,第二是组合 1:继承 描述的是类与类之间的也就是什么是什么的关系 2: 组合 描述的是类与类之间的关系, 是一种什么有什么的关系的,也 ...
- C#基础:对委托的简单理解
在编程过程中,我们习惯把数据作为参数传递给方法(例:int a=int.Parse(“20”);).是否能将一个方法传递给另一个方法呢?是不是听起来有点奇怪!!! 线程大家应该熟悉吧,在计算机中并行运 ...
- 通过HTTP请求WEBAPI的方式
平时工作中长期需要用到通过HTTP调用API进行数据获取以及文件上传下载(C#,JAVA...都会用到).这里获取的是包括网页的所有信息.如果单纯需要某些数据内容.可以自己构造函数甄别抠除出来!一般的 ...
- 4.2 手写Java PriorityQueue 核心源码 - 实现篇
上一节介绍了PriorityQueue的原理,先来简单的回顾一下 PriorityQueue 的原理 以最大堆为例来介绍 PriorityQueue是用一棵完全二叉树实现的. 不但是棵完全二叉树,而且 ...
- HDU 1556【线段树区间更新】
这篇lazy讲的很棒: https://www.douban.com/note/273509745/ if(tree[rt].l == l && r == tree[rt].r) 这里 ...
- unity5之代码创建状态机,玩的666
http://blog.csdn.net/litaog00/article/details/50483189 最近做项目的时候用到了状态机,网上搜了一下帖子,大部分都是简单介绍使用方法的,讲解的详细的 ...
- Go语言之父谈Go:大道至简
http://www.csdn.net/article/2012-07-05/2807113-less-is-exponentially-more 摘要:导读:这篇文章是Google首席工程师.Go语 ...