目录:
1、day01-Servlet 工作原理解析
2、day02-Servlet输出中文
3、day03-重定向
4、day04-容器如何处理请求资源路径?
5、day05-jsp
6、day06-状态管理
7、day07-session相关的案例
8、day08-过滤器
9、day09-Servlet线程安全问题
10、JSP隐式对象
1、day01-Servlet 工作原理解析
1. 什么是Servlet?
sun公司制订的一种用来扩展web服务器功能的组件规范。
(1)用来扩展web服务器功能
早期的web服务器(apache http server,iis等)只能够处理静态
资源的请求(即需要事先写好并存放到硬盘上,比如html文件,图片等),
不能够处理动态资源的请求(需要计算,然后生成相应的html),所以,
需要扩展其功能。
早期使用CGI程序来扩展。
CGI(了解):
Common Gateway Interface(通用网关接口),可以使用
c/c++,perl等语言来开发CGI程序。因为可移植性差,性能
也不是很好,所以现在用得很少了。
(2) 组件规范
1)什么是组件?
符合规范,实现部分功能的,并且需要部署到容器里面才能
运行的软件模块。
Servlet就是一个组件,需要部署到Servlet容器里面才能运行。
2)什么是容器?
符合规范,为组件提供运行环境的程序。
比如Tomcat(雄猫)就是一个Servlet容器。
2.如何写一个Servlet?
step1. 写一个java类,实现Servlet接口或者继承
HttpServlet类。
step2.编译。
step3.打包。
创建一个具有如下结构的文件夹:
appname (应用名,可以自定义)
WEB-INF
classes (放 .class文件)
lib (可选的,放.jar文件)
web.xml (部署描述文件)
step4.部署
将step3创建好的文件夹拷贝到容器指定的某个位置。
注:可以使用jar命令将step3创建好的文件夹进行压缩
(压缩成.war为后缀的文件),然后再拷贝。
step5.启动容器,访问Servlet
http://ip:port/appname/url-pattern
注: url-pattern在web.xml中设置。
3.Servlet是如何运行的?
比如,在浏览器地址栏输入 http://ip:port/appname/hello
step1.浏览器依据ip,port建立与服务器之间的连接。
step2.浏览器会将请求数据打包(即按照http协议的要求制作
请求数据包),然后将该数据包发送给服务器。
step3.服务器拆包(即按照http协议将请求数据包中的数据解析出来),
并将解析到的数据添加到request对象上,同时,创建一个response
对象。
step4.服务器创建servlet实例,然后调用其service方法。
注:服务器会将request对象和response对象作为参数传进来,
可以通过request对象获取请求相关的数据(比如,获得请求参数值),然后将处理结果写到response对象上。
step5.服务器将response对象上的数据取出来,打包(即按照http协议要 求制作响应数据包),然后将数据发送给浏览器。
step6.浏览器拆包,生成相应页面。
4.常见的错误
(1)404
1)含义: 依据请求路径,找不到对应的资源(
比如,找不到对应的servlet)。
注:404是一个状态码(状态码是一个三位数字,由http协议规定其含义,
表示服务器处理请求的一种状态)。
2)错误原因:
a.应用部署失败。
b.请求路径写错。
(2)500
1)含义:系统出错。
2)错误原因:
a.描述文件写错,比如,类名不正确。
b.源代码有问题。
(3)405
1)含义:找不到处理方法。
2)错误原因:
service方法不符合规范。
5.http协议(了解)
(1)什么是http协议?
是一种网络应用层协议,规定了浏览器与web服务器之间如何通信
以及相应的数据包的格式。
(2)如何通信?
step1.建立连接。
step2.发送请求数据包。
step3.发送响应数据包。
step4.关闭连接。
一次请求,一次连接。如果浏览器要向服务器发送新的请求,就需要
重新建立新的连接。
优点:服务器可以利用有限的连接为尽可能多的请求服务。
(3)数据包的格式
1)请求数据包
a.请求行 (请求类型 请求资源路径 协议类型和版本)
b.若干消息头
(了解)
消息头是一些键值对(使用": "分隔),由http协议
规定其含义,浏览器和服务器之间可以利用消息头来传递一些
特定的消息。比如浏览器可以通过发送"user-agent"消息头
来告诉服务器,浏览器的类型和版本。
c.实体内容
只有当请求类型为post时,实体内容才会有数据。
2)响应数据包
a.状态行 (协议类型和版本 状态码 状态描述)
注: 200 正常
b.若干消息头
服务器也可以发送一些消息头给浏览器,比如发送
content-type消息头,告诉浏览器,服务器返回的
数据的类型(MIME类型)。
c.实体内容
程序处理的结果,浏览器会解析出来,然后生成相应的
页面。
(4)请求类型
1)get请求
a.哪些情况下,浏览器会发送get请求?
直接在浏览器地址栏输入某个地址。
点击链接。
表单默认的提交方式。
b.特点
会将请求参数添加到请求资源路径的后面,只能提交
少量数据给服务器。
注:请求行大约只能存放约2k左右的数据。
会将请求参数显示在浏览器地址栏,不安全。
注:比如路由器就会记录请求地址(包含了请求参数)
2)post请求
a.哪些情况下,浏览器会发送post请求?
将表单的method属性设置为"post"。
b.特点
会将请求参数放到实体内容里面,能够提交大量数据
给服务器。
不会将请求参数显示在浏览器地址栏,相对安全。
注:post请求和get请求都不会对请求参数加密。
练习: 计算一个人的bmi指数: 规则: bmi指数 = 体重(公斤)/ 身高(米) / 身高(米)。 如果 bmi指数 < 19 过轻。 bmi指数 >25 过重。 否则 正常。
2、day02-Servlet输出中文
(1)为什么会有乱码?
out.println方法在输出时,默认会使用iso-8859-1来编码。
(2)如何解决?
2.读取请求参数值
(1)String request.getParameter(String paramName)
a. 如果请求参数名写错,会获得null值。
b. 对于表单(文本输入框),如果什么都不填写,会获得""。
(2)String[] request.getParameterValues(String paramName)
a.当有多个请求参数名相同时,应该用该方法。
b.对于多选框,如果一个都不选择,会获得null值。
3.表单包含有中文参数值,如何处理?
(1)为什么会有乱码?
表单提交时,浏览器会对表单中的中文参数值进行编码
(注:会使用表单所在的页面打开时使用的字符集来编码),
服务器端默认会使用iso-8859-1来解码,所以会产生乱码。
(2)如何解决?
1)post请求
request.setCharacterEncoding(String charset);
注:
a.要加到所有的getParameter方法的前面。
b.只针对post请求有效。
2)get请求
练习:添加员工
step1.建表
create table t_emp(
id number(8) primary key,
ename varchar2(50),
salary number(8,2),
age number(3)
);
create sequence t_emp_seq;
step2.实体类 (Employee)
step3.DAO类 (EmployeeDAO)
step4.addEmp.html。
step5.AddEmpServlet。
3、day03-重定向
1.重定向
(1)什么是重定向?
服务器通知浏览器向一个地址发送请求。
注:
服务器可以发送302状态码和Location消息头(值是一个地址,
称之为重定向地址),浏览器收到之后,会向重定向地址发送
请求。
(2)如何重定向?
response.sendRedirect(String url);
注:
a.url就是重定向地址。
b.重定向之前,服务器(容器)会清空response对象上存放的所有
数据。
(3)特点
a.重定向地址是任意的。
b.重定向之后,浏览器地址栏的地址会发生变化。
4、day04-容器如何处理请求资源路径?
比如,在浏览器地址栏输入
http://ip:port/servlet-day04/abc.html
step1.容器默认认为访问的是一个servlet,会从web.xml
中去查找有没有匹配的servlet。
匹配规则:
(1)精确匹配 <url-pattern>/abc.html</url-pattern>
(2)通配符匹配 (使用*匹配0个或者多个字符,比如)
<url-pattern>/*</url-pattern>
<url-pattern>/abc/*</url-pattern>
(3)后缀匹配 (以*.开头,后接任意的字符,比如)
<url-pattern>*.do</url-pattern>
匹配所有以.do结尾的请求。
step2.如果没有匹配的servlet,则查找对应的文件。
2.让一个servlet处理多种请求
step1. 采用后缀匹配。比如
<url-pattern>*.do</url-pattern>
step2. 分析请求资源路径,依据分析的结果来进行不同的处理。
3.Servlet的生命周期
(1)什么是Servlet的生命周期?
容器如何创建Servlet实例(对象),如何对其进行初始化处理,
如果调用其方法来处理请求,以及如何销毁其实例的整个过程。
(容器如何管理Servlet)。
(2)生命周期分成几个阶段?
1)实例化
a.什么是实例化?
容器调用Servlet的构造器创建对应的对象。
b.什么时候实例化?
b1.默认情况下,容器收到请求之后,才会创建其实例。
b2.容器只会创建一个实例。(单例)
b3.容器启动之后,立即创建其实例(需要额外配置)。
2)初始化
a.什么是初始化?
实例化之后,容器调用该实例的init方法。
(该方法只会调用一次)。
b.GenericServlet已经提供了init方法的实现。
会将容器传递过来的ServletConfig对象保存下来,
并且提供了一个getServletConfig方法。
c.初始化参数
step1.配置初始化参数(web.xml)
d.可以override GenericServlet提供的init方法来实现
自己的初始化处理逻辑。
注:建议override init(),而不是init(ServletConfig config)。
step2.调用ServletConfig提供的getInitParameter方法。
3)调用(就绪)
a.什么是就绪?
容器收到请求之后,会调用Servlet实例的service方法来处理请求。
b.HttpServlet已经实现了service方法。
依据请求类型来调用对应的doXXX方法。
比如,get请求会调用doGet方法,post请求会调用
doPost方法。
c.可以override HttpServlet的service方法或者override
HttpServlet的doGet,doPost方法来写处理逻辑。
4)销毁
a.什么是销毁?
容器在删除Servlet实例之前,会调用该实例的destroy方法。
(destroy方法只会执行一次)。
b.可以override GenericServlet提供的destroy方法来实现自已的
销毁处理逻辑。
(3)相关的几个接口与类(了解)
1)Servlet接口
init(ServletConfig config)
service(ServletRequest request,ServletResponse response)
destroy()
注: HttpServletRequest是ServletRequest的子接口,
HttpServletResponse是ServletResponse的子接口。
2)GenericServlet抽象类
实现了Servlet接口中的部分方法(init,destroy)
3)HttpServlet抽象类
继承了GenericServlet抽象类,主要实现了service方法。
5、day05-jsp
4. jsp (java server page)
(1)jsp是什么?
sun公司制订的一种服务器端动态页面技术规范。
注:
jsp是一个以.jsp为后缀的文件,该文件的内容主要是
html和少量的java代码。容器会将这个文件转换成一个
对应的Servlet然后执行(即jsp的本质就是一个Servlet)。
(2)如何写jsp?
step1.写一个以.jsp为后缀的文件。
step2.在该文件里面,可以添加如下内容。
1)html(css,js): 直接写。
2)java代码:
a. java代码片断
<% java代码 %>
b. jsp表达式
<%= java表达式 %>
3)隐含对象
a.什么是隐含对象?
jsp文件里面可以直接使用的对象(比如out,request,response)。
b.为什么可以直接使用这些隐含对象?
容器会自动添加获得这些对象的代码。
4)指令
a.什么是指令?
通知容器,在将jsp文件转换成Servlet类时,做一些额外的
处理,比如导包。
b.page指令
import属性:指定要导入的包,比如
<%@ page import="java.util.*,java.text.*"%>
(3)jsp是如何执行的?
阶段一 容器先将jsp文件转换成一个对应的Servlet类(.java文件)
html(css,js) -----> service方法里,使用out.write输出。
<% %> -------> service方法里,照搬。
<%= %> --------> service方法里,使用out.print输出。
阶段二 容器调用该servlet来处理请求(包括编译,实例化……)
1. jsp (java server page)
(1)jsp是什么?
sun公司制订的一种服务器端动态页面技术规范。
注:
jsp是一个以.jsp为后缀的文件,该文件的内容主要是
html和少量的java代码。容器会将这个文件转换成一个
对应的Servlet然后执行(即jsp的本质就是一个Servlet)。
(2)如何写jsp?
step1.写一个以.jsp为后缀的文件。
step2.在该文件里面,可以添加如下内容。
1)html(css,js): 直接写。
2)java代码:
a. java代码片断
<% java代码 %>
b. jsp表达式
<%= java表达式 %>
3)隐含对象
a.什么是隐含对象?
jsp文件里面可以直接使用的对象(比如out,request,response)。
b.为什么可以直接使用这些隐含对象?
容器会自动添加获得这些对象的代码。
4)指令
a.什么是指令?
通知容器,在将jsp文件转换成Servlet类时,做一些额外的
处理,比如导包。
b.page指令
import属性:指定要导入的包,比如
<%@ page import="java.util.*,java.text.*"%>
contentType属性:设置response.setContentType方法的
参数值。
pageEncoding属性:告诉容器,在读取jsp文件的内容时,
使用指定的字符集来解码。
c.include指令
file属性:指定被包含的文件。
告诉容器,在将jsp转换成servlet类时,在该指令所在的
位置插入对应的文件的内容。
(3)jsp是如何执行的?
阶段一 容器先将jsp文件转换成一个对应的Servlet类(.java文件)
html(css,js) -----> service方法里,使用out.write输出。
<% %> -------> service方法里,照搬。
<%= %> --------> service方法里,使用out.print输出。
阶段二 容器调用该servlet来处理请求(包括编译,实例化……)
2.转发
(1)什么是转发?
一个web组件将未完成的任务交给另外一个web组件继续做。
通常是一个servlet将数据获取之后转交给一个jsp来展现。
注:web组件指的是servlet或者是jsp。
(2)如何转发?
step1.将数据绑订到request对象上。
request.setAttribute(String name,Object obj);
注:
name:绑订名 obj:绑订值。
//依据绑订名获得绑订值
Object request.getAttribute(String name);
step2.获得转发器
RequestDispatcher rd =
request.getRequestDispatcher(String url);
注:
url: 转发的目的地,比如一个jsp。
step3.转发
rd.forward(request,response);
注: 转发的本质是一个web组件通知容器去调用另外一个web
组件(即调用service方法,
所以需要传递request,response)。
(3)特点
a.转发的目的地有限制(要求是同一个web应用中的某个地址)
b.转发之后,浏览器地址栏的地址不变。
(4)比较重定向和转发
a.转发所涉及的各个web组件可以共享request和response,
重定向不可以。
注:
request和responose的生存时间并不长(当服务器收到请求之后,
会立即创建这两个对象,当响应发送完毕,会立即销毁这两个对象)。
即这两个对象的生存时间为一次请求与响应期间存在。
b.转发之后,浏览器地址栏的地址不变,而重定向会变。
c.转发的目的地有限制(要求是同一个web应用中的某个地址),重定向
没有限制。
3.路径问题
(1)什么是路径问题?
链接、表单提交、重定向和转发都需要填写一个路径,比如
<form action="add.do">,如何填写这个路径。
(2)相对路径
1)什么是相对路径?
不以"/"开头的路径。
(3)绝对路径
1)什么是绝对路径
以"/"开头的路径。
2)如何写绝对路径?
链接、表单提交、重定向从应用名开始写,转发
从应用名之后开始写。
注:不要直接将应用名写在路径里面,应该使用
request.getContextPath()来获取应用名。
6、day06-状态管理
(1)什么是状态管理?
将浏览器与web服务器之间多次交互当做一个整体来处理,并且
将多次交互所涉及的数据(即状态)保存下来。
(2)如何进行状态管理?
1)将状态保存在客户端
将状态保存在浏览器这边,通常使用Cookie。
2)将状态保存在服务器端 (session 会话)
(3)Cookie
1)什么是Cookie?
服务器为了识别用户身份而临时存放在浏览器端的少量数据。
2)工作原理
浏览器访问服务器时,服务器将一些数据以set-cookie消息头
的形式发送给浏览器,浏览器会将这些数据临时保存下来;
当浏览器再次访问服务器时,会将这些数据以cookie消息头的
形式发送给服务器。
3)添加Cookie
Cookie c = new Cookie(String name,String value);
注: name: cookie名称
value: cookie值
response.addCookie(c);
4)读取Cookie
Cookie[] request.getCookies();
注: 有可能返回null。
String cookie.getName();
String cookie.getValue()
5)编码问题
a. cookie只能存放合法的ascii字符。
b. 如果要存放中文,可以将中文转换成合法的ascii字符形式。
String URLEncoder.encode(String str,String charset);
String URLDecoder.decode(String str,String charset);
注: 建议在添加cookie时,都统一编码(使用以上方法对保存的数 据进行处理)。
6)生存时间问题
cookie.setMaxAge(int seconds)
a.单位是秒。
b.sencods > 0 浏览器会将cookie保存在硬盘上,超过指定的
时间,cookie失效(删除)。
sencods < 0 默认值(浏览器会将cookie保存在内存里,浏览器 关闭,cookie会被删除)。
sencods = 0 删除cookie,比如要删除一个名称为city的cookie
Cookie c = new Cookie("city","");
c.setMaxAge(0);
response.addCookie(c);
7)cookie的路径问题
a.什么是cookie的路径问题?
浏览器访问服务器上的某个地址时,会比较请求地址是否符合
cookie的路径要求,只有符合要求的cookie才会被发送。
b.cookie的默认路径
等于添加该cookie的web组件的路径。
比如 /servlet-day06/biz01/addCookie.jsp添加了一个
cookie,则该cookie的默认路径就是 "/servletday06/biz01"
c.匹配规则
要访问的地址必须是cookie的路径或者其子路径。
比如,cookie的路径是 "/servletday06/biz01",则
/servletday06/findCookie1.jsp no
/servletday06/biz01/findCookie2.jsp yes
/servletday06/biz01/aaa/findCookie3.jsp yes
d.设置cookie路径
cookie.setPath(String path);
8)cookie的限制
a.cookie不安全。(对于敏感数据,要加密处理) 。
b.cookie可以被用户禁止。
c.cookie只能保存少量数据。(大约4k左右)。
d.浏览器端保存的cookie的数量也有限制。(大约几百个)
e.cookie只能保存字符串。
(4)session (会话)
1)什么是session?
服务器端为了保存状态而创建的一个特殊的对象。
2)工作原理
浏览器访问服务器时,服务器创建一个特殊对象session(
该对象有一个唯一的id,称之为sessionId),服务器会将
sessionId以cookie的形式发送给浏览器;
当浏览器再次访问服务器时,会将sessionId发送过来,
服务器端可以利用这个session找到对应的session对象。
3)如何获得session对象?
方式一
HttpSession session =
request.getSession(boolean flag);
注:
当flag为true时,先查看请求当中有没有sessionId,
如果没有,则创建一个session对象;
如果有,依据sessionId查找对应的session对象,如果
找到了则返回,找不到,会创建一个新的session对象。
当flag为false时,先查看请求当中有没有sessionId,
如果没有,返回null;
如果有,依据sessionId查找对应的session对象,如果
找到了则返回,找不到,返回null。
方式二
HttpSession session =
request.getSession();
等价于 request.getSession(true)。
4)几个方法
String getId()
setAttribute(String name,Object obj)
Object getAttribute(String name);
//解除绑订
removeAttribute(String name);
5)session超时
a.什么是session超时?
服务器会将空闲时间过长的session对象删除掉。
注:
这样做的好处,是为了节省内存空间的占用 。
服务器默认的超时限制一般是30分钟。
b.可以修改web.xml配置,设置超时时间限制。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
c.setMaxInactiveInterval(int seconds)
设置两次请求之间的最大间隔时间,如果超过了这个时间,
则服务器会销毁session对象。
6)删除session
invalidate()
练习:登录
step1.建表 t_user
CREATE TABLE t_user (
id number (8) PRIMARY KEY,
username varchar2 (50) UNIQUE,
PASSWORD varchar2 (20),
NAME varchar2 (100),
gender CHAR (1)
);
CREATE sequence t_user_seq;
INSERT INTO t_user
VALUES
(
t_user_seq.nextval,
'King',
'1234',
'Giving King',
'm'
);
COMMIT;
step2.实体类 (User类)
step3.DAO类 (UserDAO类)
step4.login.jsp
step5.ActionServlet (建议使用后缀匹配)
7、day07-session相关的案例
(1)session验证
step1.在登录成功之后,将一些数据绑订到session对象上。
比如
session.setAttribute("user",user);
step2.当用户请求需要保护的资源的时候(
即只有登录成功才能访问的资源),进行session验证。
Object obj = session.getAttribute("user");
if(obj == null){
//没有登录,重定向到登录页面
response.sendRedirect("login.jsp");
}
练习: 注册
用户填写注册信息(用户名,密码,真实姓名,性别)并提交,
服务器端先检查用户名是否存在,如果存在,则提示用户
“用户名已经存在”,否则,将注册信息插入到数据库并重定向
到登录页面。
练习: 生成一个验证码图片:
要求长度为5个字符,并且随机从A~Z,0~9中选取。
8、day08-过滤器
(1)过滤器是什么?
Servlet规范当中定义的一种特殊的组件,用于拦截容器的调用。
注:容器收到请求之后,如果有过滤器,会先调用过滤器,然后再
调用Servlet。
(2)如何写一个过滤器?
step1. 写一个java类,实现Filter接口。
step2. 在接口方法当中,实现拦截处理逻辑。
step3. 配置过滤器(web.xml)。
(3)初始化参数
step1.配置初始化参数。(init-param)
step2.通过FilterConfig提供的getInitParameter方法来读取
初始化参数值。
(4)优先级
当有多个过滤器都满足拦截要求,则容器依据<filter-mapping>
配置的先后顺序来执行。
2.监听器
(1)什么是监听器?
Servlet规范当中定义的一种特殊的组件,用于监听容器产生的事件。
注:有两类事件
第一类:生命周期相关的事件,指的是,当容器创建了或者销毁了
request,session,servlet上下文时产生的事件。
第二类:绑订数据相关的事件,指的是,当调用了request,session,
servlet上下文的setAttribute,removeAttribute时产生
的事件。
(2)如何写监听器?
step1. 写一个java类,实现监听器接口。
注:依据监听的事件类型选择相应的接口。比如,
要监听session创建或者销毁对应的事件,需要实现
HttpSessionListener接口。
step2. 在接口方法当中,实现监听处理逻辑。
step3. 配置监听器(web.xml)。
(3)Servlet上下文
1)什么是Servlet上下文?
容器启动之后,会为每一个web应用创建唯一的一个符合
ServletContext接口要求的对象,该对象就是Servlet上下文。
2)特点
a.唯一性:一个web应用对应一个Servlet上下文。
b.持久性:只要服务器不关闭,应用没有被卸载,则Servlet上下文
会一直存在。
3)如何获得Servlet上下文?
GenericServlet,ServletConfig,FilterConfig,
HttpSession都提供了一个方法(getServletContext )。
4)上下文的作用
a.绑订数据
setAttribute,getAttribute,removeAttribute
注:
从生存时间长度来比较(request < session < 上下文)
在满足使用条件的情况下,优先使用生命周期短的。
b.读取全局的初始化参数
9、day09-Servlet线程安全问题
过滤器优点:
a.将多个组件相同的或者类似的功能集中写在一个类里面(即
过滤器里面),方便代码的维护。
b.在不修改原有代码的基础上,增加新的功能。
(1)为什么说Servlet会有线程安全问题?
a.容器默认情况下,对于某个Servlet,只会创建一个实例。
b.容器收到一个请求,就会启动一个线程来处理请求,这样,就有可能
有多个线程同时调用同一个Servlet实例,就有可能产生线程安全问题
(比如,多个线程同时去修改某个属性)。
(2)如何解决?
a.使用synchronized对有线程安全问题的代码加锁。
注:会影响一些性能。
b.尽量避免写有线程安全的代码,比如,不要修改属性。
2. jsp基础
(1)jsp是什么?
(2)如何写jsp?
1)html 直接写
2)java代码
a. <% %>
b. <%= %>
c. jsp声明 (a1.jsp)
<%! 变量或者方法 %>
----------------------------------------
3)指令
a.什么是指令?
b.page指令
import属性:导包
pageEncoding属性:
contentType属性:
session属性 (a2.jsp):
true(缺省)/false ,当值为false时,
不能够直接使用session隐含对象了。
errorPage属性(a3.jsp):
指定一个异常处理页面。当发生异常之后,
容器会调用异常处理页面。
isErrorPage属性:(a4.jsp):
true/false(缺省),当值为true,表示这是一个
异常处理页面,可以使用exception隐含对象。
c.include指令
file属性:
d.taglib指令
用于导入jsp标签。
----------------------------------------
4)隐含对象
a.什么是隐含对象?
b.为什么可以直接使用这些隐含对象?
c.有哪一些隐含对象?
out,request,response,session,application
exception
pageContext (a6.jsp,a7.jsp)
c1. 容器会为每一个jsp实例创建唯一的一个符合
PageContext接口要求的对象。
特点:
唯一性:jsp实例对应一个pageContext。
持久性:只要jsp实例存在,pageContext
就在(不会被销毁)。
c2. 作用1: 绑订数据
注:只有对应的jsp实例才能访问
(类似钱包)。
c3. 作用2: 获得其它所有隐含对象。
config (a5.jsp)
ServletConfig
page (jsp实例)
注:jsp先转换成servlet,然后容器将这个servlet
实例化。
----------------------------------------
5)注释 (a8.jsp)
a. <!-- 注释内容 --> 注释内容如果是java代码,会执行。
b. <%-- 注释内容 --%> 注释内容如果是java代码,不会执行。
10、JSP隐式对象
JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。
JSP所支持的九大隐式对象:
对象 | 描述 |
request | HttpServletRequest类的实例 |
response | HttpServletResponse类的实例 |
out | JspWriter类的实例,用于把结果输出至网页上 |
session | HttpSession类的实例 |
application | ServletContext类的实例,与应用上下文有关 |
config | ServletConfig类的实例 |
pageContext | PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问 |
page | 类似于Java类中的this关键字 |
Exception | Exception类的对象,代表发生错误的JSP页面中对应的异常对象 |
request对象
request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。
response对象
response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。
response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。
out对象
out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。
最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用buffered='false'属性来轻松关闭缓存。
JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter新增了一些专为处理缓存而设计的方法。还有就是,JspWriter类会抛出IOExceptions异常,而PrintWriter不会。
下表列出了我们将会用来输出boolean,char,int,double,String,object等类型数据的重要方法:
方法 | 描述 |
out.print(dataType dt) | 输出Type类型的值 |
out.println(dataType dt) | 输出Type类型的值然后换行 |
out.flush() | 刷新输出流 |
session对象
session对象是 javax.servlet.http.HttpSession 类的实例。和Java Servlets中的session对象有一样的行为。
session对象用来跟踪在各个客户端请求间的会话。
application对象
application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。
这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。
通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。
config对象
config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。
这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。
以下是config对象的使用方法,不是很重要,所以不常用:
config.getServletName();
它返回包含在<servlet-name>元素中的servlet名字,注意,<servlet-name>元素在 WEB-INF\web.xml 文件中定义。
pageContext 对象
pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。
这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。
这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。
pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。
PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。
其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute("attrName")移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性:
pageContext.removeAttribute("attrName", PAGE_SCOPE);
page 对象
这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。
page 对象就是this对象的同义词。
exception 对象
exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。
(3)jsp如何执行的?
step1. 将jsp文件转换成Servlet类
html -----> service方法,使用out.write输出。
<% %> ---> service方法,照搬。
<%= %> --->service方法,使用out.print输出。
<%! %> ----> 添加新的属性或者方法。
step2. 调用Servlet。
----------------------------------------
3. jsp标签和el表达式
(1)什么是jsp标签?
jsp标签类似于html标签,用于替代jsp中的java代码。
注:因为直接在jsp中写java代码,不方便jsp文件的维护,
比如将jsp文件交给美工去修改就很不方便,所以,sun制订了
jsp标签技术规范。
----------------------------------------
(2)什么是el表达式?
是一套简单的运算规则,用于给jsp标签的属性赋值,也可以脱离
jsp标签直接使用。
----------------------------------------
(3)el表达式的基本使用
1)访问bean的属性 ( e1.jsp)
a.方式一
${user.name}
如何执行: 容器依次从pageContext,request,session,
application中查找(getAttribute方法)绑订名为"user"的对象。接下来,调用该对象的getName
方法并输出该方法的结果。
注:
a1.如果找不到对应的对象,会输出""。
a2.会将null转换成""输出。
a3.可以使用pageScope,requestScope,
sessionScope,applicationScope指定查找范围。比如 ${sessionScope.user.name}
----------------------------------------
b.方式二
${user['name']}
注:
b1. []里面可以使用绑订名。
b2. []里面可以使用从0开始的下标,用于
访问数组中的某个元素。
----------------------------------------
2)进行一些简单的运算。(e2.jsp)
注:运算结果可以直接输出,也可以给jsp标签的属性赋值。
a.算术运算 +,-,*,/,%
注: “+”只能够求和。
b.关系运算 >,>=,<,<=,==,!=
c.逻辑运算 &&,||,!
d.空运算 empty (判断集合内容是否为空,是不是一个字符串)
----------------------------------------
3)读取请求参数值 (了解 e3.jsp)
a. ${param.username}
等价于
request.getParameter("username");
b. ${paramValues.city}
等价于
request.getParameterValues("city");
(4)jstl (java standard taglib) java标准标签库
1)jstl是什么?
apache开发的一套jsp标签,后来捐献给了sun,sun
将其命名为jstl。
2)如何使用jstl?
step1.导包。
step2.使用taglib导入要使用的jsp标签。
uri属性: 指定要导入的标签的命名空间。
注:命名空间(namespace),是为了区分同名的元素而在
元素前添加的一个限定,通常是一个域名。
prefix属性:命名空间的别名。
3)几个核心标签
a. if标签 (c1.jsp)
a1. <c:if test="" var="" scope="">
标签体
</c:if>
a2.当test属性值为true,容器执行标签体的内容,可以使用el
表达式给test属性赋值。
a3.var属性用来指定一个绑订名,scope属性指定绑订范围(
"page","request","session","application")。
b.choose标签 (c2.jsp)
b1. <c:choose>
<c:when test="">
</c:when>
<c:otherwise>
</c:otherwise>
</c:choose>
b2. when可以出现1次或者多次,otherwise可以出现
0次或者1次。
c.forEach标签 (c3.jsp)
c1. <c:forEach items="" var="" varStatus="">
</c:forEach>
(5)SP的结构和生命周期
1.JSP的结构
网络服务器需要一个JSP引擎,也就是一个容器来处理JSP页面。容器负责截获对JSP页面的请求。JSP容器和Web服务器协同合作,为JSP的正常运行提供必要的运行环境和其它服务,并且能够正确识别专属于JSP网页的特殊元素。
下图显示了JSP容器和JSP文件在Web应用中所处的位置:
2.JSP处理
Web服务器是通过如下步骤使用JSP来创建网页的:
-
客户浏览器给服务器发送一个HTTP请求;
-
Web服务器识别出这是一个JSP网页的请求,并且将该请求传递给JSP引擎。通过使用URL或.jsp文件来完成;
-
JSP引擎从磁盘中载入JSP文件,然后将它们转化为servlet。这种转化只是简单地将所有模板文本改用println()语句,并且将所有的JSP元素转化成Java代码;
-
JSP引擎将servlet编译成可执行类,并且将原始请求传递给servlet引擎;
-
Web服务器的某组件将会调用servlet引擎,然后载入并执行servlet类。在执行的过程中,servlet产生HTML格式的输出并将其内嵌与HTTP的response上交给Web服务器;
-
Web服务器以静态HTML网页的形式将HTTP的response返回给浏览器;
-
最终,Web浏览器处理HTTP response中动态产生的HTML网页,就好像在处理静态网页一样;
流程如下图:
一般情况下,JSP引擎会检查JSP文件对应的servlet是否已经存在,并且检查JSP文件的修改日期是否早于servlet。如果JSP文件的修改时间早于对应的servlet,那么容器就可以确定JSP文件没有被修改过并且servlet有效。 这使得整个流程与其他脚本语言相比要高效快捷一些。
3.JSP的生命周期
理解JSP的生命周期是理解JSP底层功能的关键。
JSP的生命周期包括以下几个阶段:
-
编译阶段:servlet容器编译servlet源文件,生成servlet类;
-
初始化阶段:加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法;
-
执行阶段:调用与JSP对应的servlet实例的服务方法;
-
销毁阶段:调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例;
生命周期如下图所示:
(1)JSP编译
当浏览器发起请求时,JSP引擎将编译JSP文件。流程如下图:
有三个步骤:
-
解析JSP文件;
-
将JSP文件转化为servlet;
-
编译servlet;
这里,首先判断是不是第一次请求,如果是的话,也就是说JSP还没有被编译过,JSP引擎就把相应的JSP文件编译成servlet,生成字节码文件,并调用jspInit();如果不是第一次请求,说明已经有了字节码文件,那么就开始解析执行,调用jspServive()。
jspService()方法被调用来处理客户端的请求,对于每一个请求,JSP引擎将创建一个新的线程来处理请求。如果有多个客户端同时请求JSP文件,则JSP引擎将会创建多个线程,每个客户端对应一个线程。同时,servlet始终存在内存中,因此相应很快。
(2)JSP初始化
容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样:
[java] view plain copy
public void jspInit() {
//init code
}
通常,程序只初始化一次。
(3)JSP执行
这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。
当JSP页面完成初始化后,调用jspService()方法执行。
(4)JSP清理
JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。
jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。