目录:
01: tomcat安装配置、WEB应用部署、虚拟机配置、HTTP协议
02: 开发Servlet、Servlet继承关系、Servlet生命周期及调用过程
03: Request获取请求参数、Requeset实现请求转发、Requset作为域对象
04: Response实现重定向、实现定时刷新、ServletContext作为域对象
05: Cookie操作、CookieAPI介绍、Session工作原理、Session作为域对象
06: JSP语法、JSP指令、JSP九大隐式对象、JSP标签技术、EL、JSTL
07: 开发过滤器、过滤器详解、过滤器案例、监听器介绍、JavaWeb中的监听器
补充:
01:jsp之九大内置对象与四大域对象
01: tomcat安装配置、WEB应用部署、虚拟机配置、HTTP协议
-
TOMCAT
-
服务器概述
-
Servlet容器、WEB容器、服务器
-
-
Servlet容器:能够运行Servlet程序的环境就叫做Servlet容器
WEB容器:能够运行WEB应用程序的环境就叫做WEB容器
服务器:容器就是服务器。
2.tomcat下载和安装
2.下载
有解压版 和 安装版,还分windows 和 linux版,根据自己的需求,选择对应的版本下载.
tomcat服务器运行需要jdk的支持,版本对应为:
tomcat5 需要jdk4以上支持
tomcat6 需要jdk5以上支持
tomcat7 需要jdk6以上支持
tomcat8 需要jdk7以上支持
3.安装及启动
(1)安装
绿色版解压之后就可以使用
解压后还需要配置JAVA_HOME环境变量,指向jdk的根目录,指定tomcat启动时使用哪个jdk
环境变量配置方式:
方式一:
Path=C:\Program Files\Java\jdk1.8.0_65\bin;xxxxxxxxxx
方式二:
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_65\
Path=%JAVA_HOME%\bin;xxxxxxxx
(2)启动
通过bin/startup.bat启动tomcat
通过bin/shutdown.bat关闭tomcat
测试: 通过访问 http://localhost:8080 如果能够看到tomcat的首页就证明tomcat安装配置成功。
注意:tomcat安装路径中一定不能有中文和空格,可能一时半会没问题,但是不知道什么时候就可能出现意外。
3.Tomcat配置
4.修改默认的端口号
tomcat服务器默认监听的端口号为 8080,每次访问时都需要在主机名或IP地址后跟上端口号,如果想省略不写,将端口号修改为80即可!
找到 [tomcat]/conf/server.xml文件(tomcat服务器的核心配置文件),修改文件中(70行) 的如下配置:
将port改为80即可!!
5.端口占用问题
如果在启动时报端口占用的错误:
是因为服务器在启动的过程中监听80端口, 而该端口已经被别的进程所占用, 因此服务器启动失败!
解决方式一: 找到shutdown.bat命令, 双击运行, 将服务器按照正常的流程再关闭一次!
解决方式二: 如果是别的程序占用了80端口,导致服务器启动失败, 在cmd中通过netstat -ano命令, 查看占用80端口的进程,例如:
根据进程ID找到进程,结束即可。
也可以利用命令taskkill /f /pid 进程ID来杀死指定ID的进程
4.tomcat的目录结构
bin:tomcat批处理文件的存放目录
conf:tomcat配置文件所在的目录,其中server.xml是tomcat的核心配置文件
lib:tomcat运行时所依赖的jar包存放的目录.
logs:tomcat日志文件所在的目录
temp:tomcat运行时产生的临时文件存放的目录
webapps:是localhost虚拟主机管理的目录,放在这个目录下的web应用可以通过浏览器访问localhost主机来访问
work:tomcat运行时产生的工作文件存放目录. 是tomcat的工作目录
5.web应用
6.什么是WEB应用
将为了实现某一功能而准备好的所有的web资源按照一定的目录结构组织起来的就是一个web应用
虚拟主机不能直接管理web资源,web资源必须组织成web应用才可以交给虚拟主机去管理
7.web应用的目录结构
game
|
|-- 静态web资源,jsp 直接放在web应用的根目录下,可以通过浏览器直接访问
|-- WEB-INF web应用中特殊的目录,这个目录可以没有,一旦有了就必须符合一定的目录结构
| (放在这个目录中的资源将被保护起来,通过浏览器不能直接访问)
|--classes 用来存放动态web资源的class文件
|--lib 用来存放动态web资源所依赖的一些jar包
|--web.xml 当前web应用的核心的配置文件,web应用所有的配置操作都需要在这个文件中进行
8.部署web应用到虚拟主机中
在tomcat服务器中提供了一个虚拟主机: localhost
因此我们可以将WEB应用部署在localhost主机下.
部署方式:将组织好的WEB应用的目录直接丢进localhost主机默认管理的目录下(webapps)即可, 这种配置方式不需要重启服务器就可以起作用!
9.配置缺省的(默认的)WEB应用
在访问服务器中的WEB应用下的资源时, 如果不想写WEB应用的虚拟目录的名称, 可以将当前WEB应用配置为缺省的WEB应用. 配置方式是将WEB应用的虚拟目录名称改为ROOT即可!!
10.配置WEB应用的主页
如果在访问WEB应用下某一个资源时(比如1.html),不想书写资源的路径,可以将这个资源页配置为WEB应用的主页,在访问时就可以省略该资源的路径。
配置方式为: 在WEB应用的web.xml文件中, 添加如下配置:
6.虚拟主机
11.什么是虚拟主机
所谓的虚拟主机就是tomcat服务器中配置的一个站点,在访问时就好像访问一台真实的主机一样
tomcat服务器中可以配置多个站点,一个站点就是一台虚拟主机
12.配置虚拟主机
在[tomcat]/conf/server.xml中的server/service/Engine标签内部添加一个Host标签:
Host标签上的name是必须存在的属性,用来指定虚拟主机的名称.
Host标签上的appBase是可选属性,用来指定虚拟主机默认管理的目录,如果没有配置该属性,表示当前主机没有默认管理的目录!
配置完后,还需要在DNS服务器中配置主机名和IP地址的映射关系,但是DNS服务器一般不能修改,可以通过hosts文件进行模拟,在下面的路径中找到hosts文件:
配置如下:
13.配置缺省的(默认的)虚拟主机
如果通过主机名来访问,访问的就是对应的主机. 如果通过IP地址来访问,服务器不知道你访问的是哪一台虚拟主机,这时将会访问缺省的虚拟主机。缺省的虚拟主机配置如下:(默认是localhost)
14.综合练习
配置为www.163.com虚拟主机,部署music web应用,将WEB应用配置为缺省web应用,并且配置web应用的主页,最终实现直接访问www.163.com能够显示主页的内容.
7.其他相关
15.打war包
方式一: 进入应用的目录,用 jar -cvf xxx.war * 命令,就可以将当前目录下的所有内容打成war包,例如:
方式二: 用压缩工具打成 xxx.zip包,然后把后缀名zip改为war即可
注意:在上面打war包的两种方式中,注意压缩包中不要包含中文名称的文件!!
2.HTTP协议
8.什么是HTTP协议?
用来规定浏览器客户端和服务器之间进行通信的方式
HTTP协议中规定了浏览器该使用什么格式向服务器发送请求, 同时也规定了服务器该使用什么样的向浏览器发送响应.
9.三个基本原则
-
基于请求响应模型
-
一次请求对应一次响应
-
请求只能由客户端发出, 服务器只能被动的等待请求, 做出响应.
10.HTTP协议详解
16.HTTP请求
1.请求行(包含了请求方式、请求资源的路径、遵循的协议及版本)
GET /news3/1.html HTTP/1.1
GET:请求方式,在HTTP协议中一共规定了7种请求方式, 只用GET和POST
/news3/1.html:请求资源的路径
HTTP/1.1:浏览器发送请求时所使用的协议及版本
2.若干请求头
http协议中请求头非常多,下面列出常见的请求头及其功能:
Accept: text/html,image/*
-- 通知服务器当前浏览器可以接受那些格式的数据
Accept-Charset: ISO-8859-1
-- 浏览器可以接受的字符集编码
Accept-Encoding: gzip,compress
-- 浏览器可以接受的压缩格式
!Host: www.tedu.cn:80
-- 需要访问的虚拟主机的名称
!!Referer:http://www.tedu.cn/index.jsp
-- 这是和防盗链相关的头,对当前资源的访问来自哪个页面的超链接
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) -- 客户端的基本信息
!!!Cookie (后面讲)
-- 和cookie相关的头
Connection: close/Keep-Alive
-- 是否继续保持连接
Date: Fri, 17 Feb 2017 18:23:51 GMT
-- 当前发送请求的时间
3.请求实体内容
如果请求方式是GET提交,请求实体中没有数据
只有当请求方式为POST提交,并且请求中携带了数据, 请求实体才会有内容
4.GET请求和POST请求方式的区别
主要体现在请求参数发送过程的不相同
GET提交: 通过请求行拼接参数将数据发送给服务器
(1)通过地址栏携带参数, 非常不安全
(2)通过地址栏发送数据, 数据量不能太大(不能超过1kb或者是4kb);
POST提交: 通过请求实体内容携带参数, 数据不会显示在地址栏
(1)参数不会出现地址栏, 相对更安全
(2)数据通过请求实体内容发送, 数据量理论上没有限制.
17.HTTP响应
1.状态行
HTTP/1.1 200 OK
HTTP/1.1:服务器做出响应时遵循的协议及版本
200:状态码(一个三位的数字), 表示服务器处理请求的结果如何,200表示服务器成功的处理请求
200: 服务器成功的处理了请求
302: 和location响应头配合实现请求重定向.
304: 表示通知浏览器使用本地缓存
404: 表示客户端请求的资源不存在!
500: 表示服务器端发生了错误!
OK:描述短语, 也是用来表示服务器处理请求的结果。
2.响应头
http协议中响应头头非常多,下面列出常见的响应头及其功能:
!!!Location: http://www.tedu.cn/index.jsp
-- 配合302使用实现请求重定向
Server:apache tomcat
-- 服务器的基本信息
Content-Encoding: gzip
-- 服务器发送的数据使用的压缩格式
Content-Length: 80
-- 服务器发送的数据的大小
!!!Content-Type: text/html;charset=GBK
-- 服务器发送的数据是什么格式的,如果是字符格式的数据,则还可以通知服务器发送的数据使用的是什么编码,浏览器会根据这个头指定的编码决定使用哪个编码来打开收到的数据
!!Refresh: 1;url=http://www.tedu.cn
-- 定时刷新相关的头,通知浏览器,过几秒后自动刷新访问哪个地址
Content-Disposition: attachment;filename=aaa.zip
-- 通知浏览器以附件的形式打开发送过去的数据,是和文件下载相关的头
!!!Set-Cookie:SS=Q0=5Lb_nQ; path=/search
-- 和Cookie相关的头
!Expires: -1
-- 通知浏览器是否缓存
!Cache-Control: no-cache
-- 通知浏览器是否缓存
!Pragma: no-cache
-- 通知浏览器是否缓存
-- 之所以一个功能有三个头,是因为历史原因.所以为了网页的兼容性考虑,通常这三个头要一起使用
Connection: close/Keep-Alive
-- 是否保持连接
Date: Fri, 17 Feb 2017 18:24:11 GMT
-- 响应时的时间
3.响应实体内容
day02
-
Servlet
-
Servlet概述
-
什么是Servlet
-
-
由SUN公司提供的动态WEB资源开发技术, 本质上就是一段Java程序.
只不过这段Java程序需要放在Servlet容器(比如tomcat服务器)中才可以运行.
2.如何开发Servlet程序
1.写一个类, 并实现(直接实现或间接实现)Servlet接口
2.将编译后的class文件放在一个WEB应用中,并在WEB应用的web.xml文件中配置Servlet对外访问的虚拟路径.
3.手写一个Servlet程序
1.需求: 浏览器向服务器发送一个请求, 访问FirstServlet, FirstServlet将表示当前时间的字符串发送浏览器.
2.详细开发步骤
(1)创建一个FirstServlet.java文件
(2)编写FirstServlet类, 实现Servlet接口(或继承Servlet接口的子类), 并添加未实现的方法
(3)实现Servlet中提供的处理请求的方法service方法, 将表示当前时间的字符串响应给浏览器
(4)细节处理(添加servlet类的包路径和导入依赖包)
(5)打开CMD窗口, 编译FirstServlet类
通过命令编译会出现如下错误:
原因是 javax.servlet这个包不存在, 所有下面出现了很多找不到符号错误.
在tomcat服务器的lib目录下有servlet的jar包, 可以设置包路径:
接着再次进行编译:
(6)将FirstServlet类放在WEB应用中, 并在web.xml文件中配置Servlet对外访问的虚拟路径
将编译好的class文件(包括包路径)放在web应用的classes目录下.
在WEB应用的web.xml文件中配置servlet对外访问的虚拟路径:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>com.tedu.servlet.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/FirstServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>1.html</welcome-file>
</welcome-file-list>
</web-app>
(7)将WEB应用部署到虚拟主机中, 启动服务器, 通过浏览器访问FirstServletServlet.
2、Servlet继承关系
Servlet继承关系
Servlet接口 -- 提供了一个Servlet类应该具有功能
|
|-- GenericServlet(抽象类) -- 实现了Servlet接口, 并实现了Servlet接口中大部分的方法, 但是没有实现service方法, 这个方法需要开发人员自己来实现.
|
|-- HttpServlet(抽象类) -- 继承了GenericServlet, 并且实现了service方法, 在Service方法中: 根据不同的请求方式, 调用不同的doXxx方法.
因此, 以后我们在开发中, 如果要写一个Servlet程序, 只需要写一个类继承HttpServlet, 并覆盖doGet和doPost方法, 分别来处理GET请求和POST请求.
3.Servlet调用过程
开发一个Servlet程序, 将Servlet放在WEB应用中, 并将WEB应用部署在服务器中运行. 打开浏览器访问Servlet程序, 这个Servlet程序是如何被调用的? 又是如何执行的?
详细过程参见<<Servlet调用过程>>图解
4、Servlet生命周期
5、请求参数乱码图解
6、请求重定向
7、请求转发
4.Servlet开发细节
7.Servlet在web.xml文件中虚拟路径的配置
开发一个Servlet程序之后, 需要在web应用的web.xml文件中配置该Servlet对外访问的虚拟路径, 虚拟路径的配置方式有两种
1.直接写一个路径, 比如:/FirstServlet /servlet/SecondServlet1
2.通过星号( * )匹配符来配置虚拟路径
(1) 以斜杠( / )开头, 以斜杠星( /* )结尾, 比如: /* /servlet/*...
(2) 以 *.后缀 的形式, 比如: *.do *.action *.jsp....
通过*号匹配符配置路径, 可以使得路径的访问变得更加灵活, 但是也可能会导致一个路径会被多个mapping所匹配, 具体哪一个Servlet将会执行, 优先级规则如下:
优先级规则:
(1) 哪一个更像(更精准)哪一个将会起作用
(2) *.后缀的优先级永远最低
示例:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
(1) 当请求URL为“/abc/a.html”,“/abc/*”和“/*”都匹配,哪个servlet响应
ServletDemo1将会执行!
(2) 当请求URL为“/abc”时,“/abc/*”和“/abc”都匹配,哪个servlet响应
ServletDemo3将会执行!
(3) 当请求URL为“/abc/a.do”时,“/abc/*”和“*.do”都匹配,哪个servlet响应
ServletDemo1将会执行!
(4) 当请求URL为“/a.do”时,“/*”和“*.do”都匹配,哪个servlet响应
ServletDemo2将会执行!
8.修改Servlet模版
day03
1 Request
1.1 Request继承关系
ServletRequest接口 -- 提供了一个request对象应该具有的功能||-- HttpServletRequest接口,继承了ServletRequest接口,并添加了很多和HTTP协议相关的方法
1.2 Request功能
1.2.1 获取客户机基本信息、获取请求头信息
(1) getRequestURL() -- 获取发送请求的完整URL
(2) getRequestURI() -- 获取请求行中的请求资源路径
(3) getRemoteAddr() -- 获取客户机的ip地址
(4) getMethod() -- 获取发送请求的方式
(5) getContextPath() -- 获取当前WEB应用的虚拟路径,在开发中,如果需要写当前WEB应用的虚拟路径,路径最好不要写死,而是通过getContextPath方法动态获取!
(1) getHeader(String name) -- 根据请求头的名称获取指定的值
1.2.2 获取请求参数(!!)
getParameter(String name) -- 通过请求参数的名称获取对应的参数值getParameterValues(String name) -- 通过请求参数的名称获取对应的多个参数值组成的数组getParameterMap() -- 获取所有请求参数组成的map集合
String username = request.getParameter("username");System.out.println("解决前,username: "+username);//乱码!!!
byte[] bytes = username.getBytes("iso8859-1");
username = new String(bytes, "utf-8");System.out.println("解决后,username: "+username);
request.setCharacterEncoding("utf-8");String username = request.getParameter("username");System.out.println("username: "+username);
request.setCharaterEncodign();
1.2.3 实现请求转发(!!)
request.getRequestDispatcher (“demo.jsp"). forward(request, response);//转发到demo.jsp
1.2.4 作为域对象使用(!!)
-
创建两个 Servlet
1.实现请求包含
-
创建三个 Servlet
1 Response
1.1 Response继承关系
ServletResponse接口 – 提供了一个Response对象应该具有的功能||-- HttpServletResponse接口 – 继承了ServletResponse, 并且在此基础上添加了很多和Http协议相关的方法.
1.2 Response常用方法
HTTP/1.1 200 OK
xxx: xxxxxx: xxx...
xxxxx
setStatus()
setHeader()
getOutputStream()getWriter()
1.3 Response对象的功能
1.3.1 向客户端浏览器发送数据
//>>向外发送数据(英文)response.getOutputStream().write( "Hello response!".getBytes());
//>>向外发送中文数据//getBytes方法默认使用GBK来发送数据。response.getOutputStream().write("哈喽 response!".getBytes());
//指定浏览器在接收数据时也使用utf-8response.setContentType("text/html;charset=utf-8");//指定在服务端使用utf-8来发送数据(getBytes方法默认使用GBK来发送数据。)response.getOutputStream().write("哈喽 response!".getBytes("utf-8"));
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");response.getWriter().write("哈喽 reponse!");
/* 这行代码既会通知服务器使用utf-8发送数据,* 也会通知浏览器使用utf-8来接收数据 */response.setContentType("text/html;charset=utf-8");response.getWriter().write("哈喽 reponse!");
response.setContentType("text/html;charset=utf-8");response.getOutputStream().write("哈喽 reponse!".getBytes("utf-8"));
response.setContentType("text/html;charset=utf-8");response.getWriter().write("哈喽 reponse!");
1.3.2 实现请求重定向
response.setStatus(302);response.setHeader("location", "url地址");
response.sendRedirect("uri地址");
response.sendRedirect("/day14/param.html");response.sendRedirect("http://tmooc.cn");
1.3.3 实现定时刷新
//提示用户注册成功, 3秒之后将会跳转到主页//>>处理响应正文乱码response.setContentType("text/html;charset=utf-8");response.getWriter().write("恭喜您注册成"+ "功! 3秒之后将会跳转到主页...");//实现3秒之后刷新到主页response.setHeader("refresh","3;url=/day15/index.html");
1.4 三种资源跳转方式的区别和使用场景
-
三种资源跳转方式的区别
(1)一次请求,一次响应(request对象是同一个)
(4)定时刷新和重定向主要的区别在于,重定向是立即跳转,而定时刷新是在指定多少秒之后立即跳转,并且在跳转之前,可以向浏览器发送响应数据并维系一段时间.
2.三种资源跳转方式的使用场景
(2)如果没有什么特殊需要,两种方式都可以.
读取数据乱码设置
|
//请求参数乱码post或get提交的参数
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"), "utf-8");
//请求参数乱码post提交的参数
request.setCharacterEncoding("utf-8");
|
发送数据乱码
|
//指定服务端发送数据使用utf-8
response.setCharacterEncoding("utf-8");
|
浏览器乱码解码设置
|
//(2)指定浏览器接收数据也是用utf-8
response.setContentType("text/html;charset=utf-8");
|
转发
|
request.getRequestDispatcher
(“demo.jsp").forward
(request,response);
|
1.转发在服务器端完成的;
2.转发的速度快;
3.转发的是同一次请求;
4.转发不会执行转发后的代码;
5.转发地址栏没有变化;
6.转发必须是在同一台服务器下完成;
|
重定向
|
response.sendRedirect("uri地址");
|
1、重定向是在客户端完成的
2、重定向速度慢
3、重定向是两次不同请求
4、重定向会执行重定向之后的代码
5、重定向地址栏有变化
6、重定向可以在不同的服务器下完成
|
定时刷新
|
response.setHeader("refresh",
"3;url=/day15/index.html");
|
(1)
两次请求
,
两次响应
(2)
地址栏地址会发生变化
(3)
request
对象不是同一个
(4)
既可以实现在不同的
WEB
应用或者不同的主机之间进行跳转
,
也可以实现在同一个
WEB
应用内的资源之间进行跳转
(5)
和重定向不同的是
,
定时刷新可以实现在多少秒之后再
进行跳转
,
而重定向是立即跳转
!
|
2 ServletContext
2.1 概述
2.1.1 什么ServletContext对象
2.2 获取ServletContext对象
ServletContext context = this.getServletContext();
2.3 作为域对象使用
2.3.1 作为域对象使用
setAttribute(String name, Object value) -- 往ServletContext域中添加一个域属性.getAttribute(String name) -- 通过属性名称获取指定名称的属性removeAttribute(String name) -- 通过属性名称删除指定名称的属性getAttributeNames() -- 获取所有属性名称组成的枚举
(1)生命周期:WEB应用被加载之后,服务器会立即创建代表当前WEB应用的ServletContext对象,服务器关闭或者WEB应用被移出容器,ServletContext对象将会销毁.(2)作用范围:在整个WEB应用范围内(3)主要功能:在整个 WEB应用范围内实现资源的共享
//设置ServletContext对象
ServletContext context = this.getServletContext();
context.setAttribute("name", "尼古拉斯赵四");
context.setAttribute("age", 38);
context.setAttribute("addr", "东北");
System.out.println("demo1...");
//获取ServletContext对象
ServletContext context = this.getServletContext();
//获取ServletContext域中的数据
String name = (String) context.getAttribute("name");
int age = (Integer) context.getAttribute("age");
String addr = (String) context.getAttribute("addr");
System.out.println(name+" : "+age+" : "+addr);
2.3.2 案例:统计网站访问人次
//1.获取ServletContext对象
ServletContext context = this
.getServletContext();
/* 2.判断ServletContext域中是否包含统计
* 访问次数的计数器
*/
int count = 0;
if(context.getAttribute("count") == null){
//>>如果是第一次访问, 将计数器存入域中
context.setAttribute("count", ++count);
}else{
//>>如果不是第一次访问, 取出计数器+1再存入域中
count = (int) context.getAttribute("count");
context.setAttribute("count", ++count);
}
//3.响应
response.setContentType(
"text/html;charset=utf-8");
response.getWriter().write(
"您是第"+count
+"位访问本网站的用户...");
day06
-
会话技术
-
会话技术概述
-
什么是会话?
-
-
为了实现某一个功能,浏览器和服务器之间可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束,关闭浏览器为止,这期间产生的多次请求和响应加在一起,就称之为浏览器和服务器之间的一次会话。
2.如何保存会话中产生的数据?
在这里我们可以尝试使用之前学习过的两个域对象:request和ServletContext对象,但是
request域太小了
ServletContext域太大了
我们可以使用会话技术中的两门技术,分别是Cookie和Session
2.Cookie
-
Cookie保存数据的原理
浏览器访问服务器,服务器获取到需要保存的数据,并将数据通过Set-Cookie响应头将数据再次发送给浏览器,让浏览器自己保存。
当浏览器再次访问服务器时,会通过请求中的Cookie请求头将上次保存的Cookie信息带给服务器,服务器可以获取请求中的数据,从而实现某些功能。
Cookie是将会话中产生的数据保存在了客户端,所以Cookie是客户端技术。如果每个客户端各自保存自己的数据,当需要时在带给服务器,就不会产生混乱。
2.Cookie的API
SUN公司为了简化Cookie的操作,为我们提供了一套Cookie的API
1、创建Cookie
Cookie cookie = new Cookie(String name, String value);
2、添加Cookie到response对象中
response.addCookie(Cookie cookie) – 将cookie对象添加到响应中
3、如何获取请求中的Cookie
Cookie[] cs = request.getCookies() – 获取当前请求中所有的cookie对象组成的数组
4、如何删除Cookie
Cookie的API中没有提供直接删除Cookie的方法
如果要删除之前发送的一个Cookie,
1.我们可以向浏览器再发送一个同名/同path的Cookie, 浏览器收到后会用现发的Cookie覆盖之前发送的Cookie,
2.如果现发的Cookie设置setMaxAge方法为0, 浏览器也会删除现发的Cookie, 这样以来就可以将之前发送的Cookie和现发的Cookie统统删除!
示例:
//1.创建一个Cookie(要和被删除的Cookie同名)
Cookie cookie = new Cookie("time", "");
//2.设置Cookie的path(path也相同)
cookie.setPath(request.getContextPath()+"/");
//3.设置Cookie的存活时间为0
cookie.setMaxAge(0);
//4.将Cookie添加到response响应中
response.addCookie(cookie);
response.getWriter().write(
"cookie delete success!");
5、Cookie中常用的方法
cookie.getName() – 获取cookie的名字
cookie.getValue() – 获取Cookie的value值
cookie.setValue() – 设置Cookie的value值
cookie.setMaxAge() – 设置Cookie的最大存活时间
cookie.setPath() – 设置Cookie的路径
6.setMaxAge – 设置Cookie的最大存活时间
如果不设置这个方法, Cookie默认是会话级别的Cookie, Cookie是保存在浏览器的内存中的, 如果浏览器关闭, 随着浏览器内存的释放, Cookie也会跟着销毁!
如果设置了这个方法, Cookie就不在保存在内存中了, 而是以文件的形式保存在浏览器的临时文件夹中(在硬盘的某一个位置)
示例:
...
//2.将本次时间发送给浏览器保存
//>>创建一个Cookie对象
Cookie timeCookie =
new Cookie("time",dateStr);
//>>设置Cookie的最大存活时间( 3600*24/秒 )
timeCookie.setMaxAge( 3600*24 );
//>>将Cookie添加到响应中(发送给浏览器)
response.addCookie( timeCookie );
...
7.setPath – 设置Cookie在浏览器访问哪一个路径及其子孙路径时将会被带回去(服务器)
如果不设置该方法, Cookie的path默认是发送Cookie的Servlet所在的路径.
比如: 发送Cookie的Servlet为CookieDemo2
CookieDemo2的访问路径为 :
http://localhost/day16/CookieDemo2
此时Cookie的path就是: /day16/
如果Cookie的路径为/day16/也就意味着, 浏览器在访问day16应用下任何一个资源时将会带着Cookie.
因此如果希望浏览器在访问当前应用下任何资源时都能够带着Cookie, 最好将cookie的path设置为 当前WEB应用根路径, 比如:
cookie.setPath( request.getContextPath()+"/" );
3.案例:在网页中显示上次访问的时间
1、通过传统方式实现
//0.处理响应正文乱码
response.setContentType(
"text/html;charset=utf-8");
//1.获取(记录)本次访问的时间
String dateStr = new Date()
.toLocaleString();
//2.将本次访问时间发送给浏览器保存
response.setHeader("Set-Cookie",
"time="+dateStr);
//3.获取浏览器上次访问的时间(Cookie)
String dateStr2 = request
.getHeader("cookie");
//4.判断是否具有保存上次访问时间的Cookie
if(dateStr2 != null){
//>>如果有Cookie,则响应浏览器上次访问时间
response.getWriter().write(
"您上次访问的时间为:"
+dateStr2);
}else{
//>>如果没有Cookie,则响应浏览器是第一次访问
response.getWriter().write(
"您是第一次访问本网站!");
}
2、通过Cookie的API实现
//0.处理响应正文乱码
response.setContentType("text/html;charset=utf-8");
//1.获取(记录)本次访问的时间
String dateStr = new Date().toLocaleString();
//2.将本次时间发送给浏览器保存
//>>创建一个Cookie对象
Cookie timeCookie = new Cookie("time",dateStr);
//>>将Cookie添加到响应中(发送给浏览器)
response.addCookie( timeCookie );
//3.获取当前请求中所有cookie组成的数组
Cookie[] cs = request.getCookies();
//>>遍历Cookie数组,获取名称为time的Cookie
if(cs != null){
for(Cookie c : cs){
//4.判断请求中是否包含上次访问时间的Cookie
//>>如果包含,则响应上次访问时间
if( "time".equals(c.getName()) ){
//响应上次访问的时间
response.getWriter().write("您上次访问的时间为: "+c.getValue());
return;
}
}
}
//>>如果不包含,则响应是第一次访问
response.getWriter().write("您是第一次访问本网站!");
4.可能遇到的问题
如果通过Cookie对象向浏览器发送Cookie信息, 并且cookie的value值中包含了中文字符, 例如:
Cookie timeCookie = new Cookie("time", "2018年3月32日 13:13:13");
在响应时会抛出如下异常:
解决方法为:
(1) 在发送数据时,如果cookie的value值中包含中文, 则对value值进行URL编码即可, 例如:
Cookie timeCookie = new Cookie("time", URLEncoder.encode( "2018年3月32日 13:13:13","utf-8"));
(2)由于之前对value值做了URL编码, 所以再次获取数据时需要对value进行URL解码, 例如:
response.getWriter().write("您上次访问的时间为: " +URLDecoder.decode(c.getValue(),"utf-8"));
3.Session
-
Session保存数据的原理
浏览器发请求访问服务器,服务器获取到需要保存的数据,获取到为当前浏览器服务session对象,将数据保存在session中。
当浏览器下载访问服务器时,服务器会找到为浏览器服务的session,从中取出数据,从而实现某些功能。
session是将会话中产生的数据保存在了服务器端,是服务器端的技术。如果将各个浏览器所需要保存的数据保存在各自对应的session对象中,当需要时再从session取出来,自然也不会混乱!(一个浏览器一个session对象)
2.Session是域对象
1.域对象提供的方法
setAttribute(); -- 添加一个域属性/修改已有的域属性值
getAttribute(); -- 根据属性名称获取指定名称的属性值
removeAttribute(); -- 根据属性名称删除指定名称的属性
getAttributeNames(); -- 获取所有属性名称组成的枚举 集合
2.域对象的特征
生命周期:
(1)创建Session对象: 当第一次调用request.getSession方法时创建session.
request.getSession()
request.getSession(true)
上面这两个方法在获取session时: 如果服务器中有为当前浏览器服务的session, 就直接拿过来使用. 如果没有session, 就创建一个session拿过来使用.
request.getSession(false)
上面这个方法在获取session时: 如果服务器中有为当前浏览器服务的session, 就直接拿过来使用. 如果没有session, 就返回null.
(2)销毁session对象:
a) 超时销毁:如果超过30分钟没有操作session, session将会超时销毁(在web.xml文件中可以修改session的超时时间)
b) 自杀:当调用session的invalidate方法将会立即销毁session
c) 意外身亡:当服务器非正常关闭, 服务器中的session会立即销毁, 如果服务器是正常关闭, session并不会销毁, 而是以文件的形式保存到硬盘上, 这个过程叫做session的钝化.
当服务器再次开启时, 钝化着的session还会恢复回来, 这个过程叫做session的活化.
session序列化文件的存储位置:
..\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\day16
作用范围:一次会话
主要功能:在整个会话范围内实现资源的共享
3.案例: 实现购物案例
1.创建prodList.html页面, 用于展示商品信息
代码实现:
<h1>点击下列商品将商品加入购物车</h1>
<a href="/day16-servlet-05-cookie/ShoppingSession?prod=小米手机">小米手机</a><br/><br/>
<a href="/day16-servlet-05-cookie/ShoppingSession?prod=海尔洗衣机">海尔洗衣机</a><br/><br/>
<a href="/day16-servlet-05-cookie/ShoppingSession?prod=Iphonex">Iphonex</a><br/><br/>
<a href="/day16-servlet-05-cookie/ShoppingSession?prod=阿迪王皮鞋">阿迪王皮鞋</a><br/><br/>
<a href="/day16-servlet-05-cookie/ShoppingSession?prod=vivox20">vivox20</a><br/><br/>
<a href="/day16-servlet-05-cookie/ClearingSession">支付</a><br/><br/>
</body>
2.创建ShoppingSession, 用于将请求中的商品加入购物车
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理响应正文乱码
response.setContentType("text/html;charset=utf-8");
//获取请求参数
String prod = request.getParameter("prod");
//处理请求参数乱码
prod = new String(prod.getBytes("iso8859-1"),"utf8");
//2.获取session对象
HttpSession session = request.getSession();
/*
* Session创建成功后, 服务器会为其分配ID,
* 并将ID作为Cookie发送给浏览器保存,但是
* 这个Cookie是一个会话级别的Cookie,
* 浏览器关闭Cookie就会丢失(ID也会丢失),
* Cookie丢失, session就再也找不到了.
*/
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(60);
response.addCookie(cookie);
//3.将商品信息保存到购物车中
session.setAttribute("prod", prod);
response.getWriter().write("成功的将商品"+prod+"添加到购物车");
}
3.创建ClearingSession, 用于对购物车中的商品进行结算
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
String prod = session.getAttribute("prod").toString();
if(prod!=null) {
response.getWriter().write("已结算商品"+prod);
}else {
response.getWriter().write("你还购物车没有商品");
}
}
4.获取浏览器关闭之前的session
如果在session中保存了数据, 将浏览器关闭, 再次打开浏览器访问服务器, 会发现无法找到之前的session. 也无法获取之前保存的数据了.
原因是: Session创建成功后,服务器会为其分配一个独一无二的编号就是ID,并将ID作为Cookie发送给浏览器保存,但是这个Cookie是一个会话级别的Cookie,浏览器关闭后, Cookie就会丢失, 在Cookie中保存的ID也会丢失, 下次浏览器去访问服务器, 就再也找不到之前的session了.
解决方案: 上面的问题是因为服务器发送保存sessionID的cookie是会话级别的cookie, 所以在浏览器关闭后才会丢失, 导致找不到session.因为我们可以自己向浏览器发送一个名称为JSESSIONID的Cookie, 值保存的就是session的ID, 并且path为当前WEB应用的根路径. 最重要的是设置Cookie的生存时间为一个正值(比如30分钟), 这样我们自己发送的Cookie就会持久保存到硬盘上, 不会随着浏览器的关闭而销毁.
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setPath(request.getContextPath()+"/");
cookie.setMaxAge(60);
response.addCookie(cookie);
day07
-
JSP
-
JSP 概述
-
JSP介绍
-
-
2.JSP技术的由来
3.修改JSP模版
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
</head>
<body>
${cursor}
</body>
</html>
2.JSP语法
-
模版元素
直接写在jsp页面中的html内容称之为jsp页面中的模版元素
模版元素在翻译过来的Servlet中被out.write()原样输出到浏览器中
比如:
模版元素在JSP翻译后的Servlet中直接被out.write原样输出. 如下:
2.JSP表达式
格式: <%= 表达式 %> 其中可以书写常量、变量、表达式。
JSP表达式在翻译后的Servlet中是执行表达式的值再原样输出到浏览器,例如
(1)在JSP页面编写内容如下:
<%= request.getContextPath() %> <br/>
<%= "Hello...JSP..." %> <br/>
(2)在翻译后的Servlet中翻译如下:
3.JSP脚本片段
格式:<% 若干java语句 %>
在翻译过来的servlet中,脚本片段被复制粘贴到对应位置执行
翻译前:
<% for(int i=0; i<5; i++){ %>
Hello JSP~~~~~<br/>
<% } %>
翻译后:
for(int i=0; i<5; i++){
out.write("\r\n");
out.write("\t\tHello JSP~~~~~<br/>\r\n");
out.write("\t");
}
在某一个脚本片段中的java代码可以是不完整的,但是要求在翻译过来的servlet中整体的代码必须是完整符合java语法的.
4.JSP注释:
格式: <%-- JSP注释 --%>
例如:<%-- out.write("aaa"); --%> 被JSP注释注释的内容,在翻译的过程中被抛弃,不会被翻译。
5.JSP指令
JSP指令格式:<%@ 指令名称 若干属性声明... %>
-- 不会直接产生输出,用来指挥JSP解析引擎如何来翻译当前JSP页面中其他部分的内容(除指令意外的其他内容,例如模版元素、jsp表达式等)
1.page指令
-- 用来声明当前JSP页面的基本属性的,page指令可以写在JSP页面的任意位置,但是为了可读性考虑,一般情况下最好放在JSP页面的最前面
格式: <%@ page ... %>
(1)<%@ page language="java" %> -- 指定当前JSP使用的语言是java.(了解即可)
(2)<%@ page pageEncoding="UTF-8"%> -- 用来通知JSP解析引擎使用指定的编码来翻译JSP。如果想防止JSP乱码,应该要保证JSP文件保存时的编码和pageEncoding指定的编码保持一致。
(3)<%@ page session="true"%> -- 用来指定当前页面是否使用session,如果设置为true,则翻译过来的servlet中将会有对session对象的引用,于是可以直接在JSP中使用session隐式对象。但是这将导致一旦访问JSP就会调用request.getSession()方法,可能导致不必要的空间浪费。如果确定JSP中不需要session可以设为false
(4)<%@ page errorPage="filepath"%> -- 为当前JSP页面指定友好错误提示页面,即当前JSP如果抛出了异常,将会跳转到errorPage属性指定的页面。
扩展:如果整个WEB应用中有很多JSP都需要指定错误提示页面,如果挨个为每一个JSP通过errorPage来指定,非常繁琐,所以推荐在web.xml文件中为整个网站的异常统一配置友好错误提示页面,配置如下:
(5)<%@ page import="..."%> -- 为JSP翻译后的Servlet指定所依赖的jar包.例如:
<%@page import="java.util.Date"%>
<%@page import="java.io.File" %>
<%@page import="java.sql.DriverManager"%>
2.include指令
-- 可以实现页面包含的效果
格式:<%@ include file="" %>
示例: 创建三个JSP文件(分别为head.jsp,body.jsp,foot.jsp),在body.jsp中包含head.jsp和foot.jsp,最终实现将三个文件的内容一起响应给浏览器.
(1)创建三个JSP文件(分别为head.jsp,body.jsp,foot.jsp)
(2)分别实现三个JSP文件的内容如下:
a)_head.jsp
<%@ page language="java"
pageEncoding="utf-8"%>
<h1 style="background-color:pink;height:200px;">
网页的头部部分
</h1>
b)body.jsp
<%@ page language="java"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- 引入头部 -->
<%@include file="/include/_head.jsp" %>
<h1 style="background-color:red;height:400px;">
网页的主体部分
</h1>
<!-- 引入尾部 -->
<%@include file="/include/_foot.jsp" %>
</body>
</html>
c)_foot.jsp
<%@ page language="java"
pageEncoding="utf-8"%>
<h1 style="background-color:cyan;height:100px;">
网页的尾部部分
</h1>
(3)测试: 浏览器访问的结果为:
3.taglib指令
导入tld标签库文件
3.JSP的九大隐式对象
JSP翻译引擎在将JSP翻译成servlet的过程中,在servlet里预先定义了九个对象,因此我们可以在JSP页面中直接使用这九个对象
page this
request ServletRequest
response ServletResponse
application ServletContext
config ServletConfig
session HttpSession
exception
out 等价于response.getWriter()
pageContext 当前jsp运行环境的对象
-
pageContext对象
代表当前JSP页面的运行环境的对象,通过该对象可以访问页面中的共享数据
1.pageContext对象可以获取其他八大隐式对象
(1)pageContext.getPage(); -- 获取page隐式对象
(2)pageContext.getRequest(); -- 获取request隐式对象
(3)pageContext.getResponse(); -- 获取response隐式对象
(4)pageContext.getServletContext(); -- 获取application隐式对象
(5)pageContext.getServletConfig(); -- 获取config隐式对象
(6)pageContext.getSession(); -- 获取session隐式对象
(7)pageContext.getException(); -- 获取exception隐式对象
(8)pageContext.getOut(); -- 获取out隐式对象
2.pageContext是一个域对象
setAttribute(String name,Object value) – 添加一个域属性
getAttribute(String name) – 根据指定的属性名获取属性值.
removeAttribute(String name) – 根据指定的属性名删除一个属性.
生命周期:当访问JSP开始时创建pageConext对象,当访问JSP结束时销毁pageContext对象.
作用范围: 整个JSP页面
主要功能: 在整个JSP页面中实现数据的共享
4.JSP标签技术
在JSP页面中写入大量的java代码会导致JSP页面中html代码和java代码混杂在一起,会造成页面非常的混乱,难于维护
于是在JSP的2.0版本中,sun提出了JSP标签技术,推荐使用标签来代替JSP页面中java代码,并且推荐,JSP2.0以后不要在JSP页面中出现任何一行java代码。
-
EL表达式
EL表达式在JSP中可以非常方便的获取数据,可以代替JSP页面中的JSP表达式(<%= %>)
基本结构: ${ 表达式 }
EL只能获取不能设置!!!
EL只能获取不能遍历!!!
EL表达式提供了如下功能:
(1)EL可以获取常量/变量(必须存入域中)/表达式的值
(2)EL可以获取域中的数组或集合中的数据
获取域中集合中的数据和获取数组的方式相同. 这里不再举例
(3)EL可以获取域中的Map集合中的数据。
2.JSTL标签库
jstl包:
文件寻贴主得
JSTL标签库是为JavaWeb开发人员提供的一套标准通用的标签库,JSTL标签库和EL配合使用取代JSP中大部分的Java代码.
<%@ taglib uri="Oracle Java Technologies | Oracle" prefix="c" %>
(1)var – 指定存入域中属性的名称(2)value -- 指定存入域中属性的值(3)scope – 指定将属性如此哪一个域中(4)target – 指定修改域中的哪一个集合,比如:<c:set target="${map}"...(5)property – 指定修改域中集合中的哪一个属性
<c:if test="${3>5}">yes</c:if><c:if test="${!(3>5)}">no</c:if>
${pageContext.getRequest().getContextPath()}或:${pageContext.request.contextPath}
(1)items: 指定需要遍历的集合或数组(2)var: 指定用于接收遍历过程中的元素(3)begin: 指定循环从哪儿开始(4)end: 指定循环到哪儿结束(5)step: 指定循环时的步长(6)varStatus="status" 返回一个表示循环状态的对象,该对象还具有如下属性:a)count:表示当前遍历的元素是第几个 b)first:表示当前遍历的元素是否为第一个c)last:表示当前遍历的元素是否为最后一个 d)index:表示当前遍历元素的索引(从零开始)
day08
-
过滤器
-
过滤器概述
-
什么是过滤器?
-
-
Servlet技术规范中,定义了Servlet、Filter、Listener三门技术, 其中Filter也叫做过滤器,通过过滤器技术,开发人员可以实现用户在访问某个资源之前或之后,对访问的请求和响应进行拦截,从而做一些相关的处理。
总结:
1.所谓的过滤器,就是拦截用户对资源的访问
2.一个过滤器可以拦截多个资源,一个资源也可以配置多个过滤器进行拦截
3.其实所谓的拦截,就是将代表请求的request对象和代表响应的response对象拦截下来,拦截下来后:
(1)控制是否允许访问 – 比如:用户登陆之后才能访问自己的订单或购物车
(2)在访问资源之前或之后做一些处理 比如: 全站乱码解决
2.开发过滤器
-
开发过滤器的步骤
Servlet API中提供了一个Filter接口,开发web应用时,如果编写一个类实现了这个接口,则这个类就是一个过滤器类。
(1)写一个类实现Filter接口,并实现其中的方法
(2)在web应用的web.xml中配置过滤器
2.过滤器的配置
在创建完Filter类之后,需要在web应用的web.xml文件中配置过滤器所要拦截的资源路径,具体配置如下:
3.过滤器案例1
1、需求:创建两个Servlet,分别为ServletDemo1和ServletDemo2.分别来处理不同的请求。创建一个过滤器并配置过滤器拦截浏览器对ServletDemo1和ServletDemo2的访问.
2、实现步骤:
(1)创建两个Servlet,分别是ServletDemo1和ServletDemo2。
(2)ServletDemo1代码实现如下
(2)ServletDemo2代码实现如下
(3)测试ServletDemo1:
(4)测试ServletDemo2:
(5)创建一个过滤器,实现Filter接口
(6)FilterDemo1中doFilter方法的实现:
(7)配置过滤器对两个Servlet进行拦截.
(8)分别访问ServletDemo1和ServletDemo2,查看FilterDemo是否会对这两资源的请求进行拦截处理.
4.过滤器案例2
改造上面的过滤器案例,允许用户在访问之前,在请求中携带两个“暗号“,接着配置两个过滤器对访问ServletDemo1和ServletDemo2的请求进行拦截,拦截之后判断输入的暗号。例如第一个过滤器判断第一个暗号,第二个过滤器判断第二个暗号。只有当两个暗号都正确时,才允许访问ServletDemo1和ServletDemo2。只要有一个过滤器判断暗号错误,将会跳转到提示页面提示暗号错误。
(1)编写code.jsp用来让用户输入暗号
(2)编写error.jsp用来提示(当用户输入的暗号不正确时,跳转到error页面进行提示)
(2)修改FilterDemo1中doFilter方法,对拦截的请求进行处理:获取请求中携带的暗号并判断暗号是否正确,如果不正确就跳转到error.jsp提示用户暗号错误,如果正确就放行访问ServletDemo1。
(3)测试访问
(4)创建FilterDemo2判断第二个暗号是否正确(自己实现)
3.过滤器中的方法
-
init方法
public void init(FilterConfig arg0)
-- 当Filter实例创建之后,服务器立即调用init方法进行初始化的操作.
2.doFilter方法
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException
-- 当过滤器拦截到对资源的访问时,服务器会调用doFilter方法进行处理.
参数FilterChain代表多个过滤器组成的过滤器链对象.
(1)一个资源可以配置多个过滤器进行拦截,多个过滤器执行的顺序是按照Filter在web.xml中对应的filter-mapping标签的先后配置顺序执行的.多个过滤器就组成了一条过滤器链.
(2)当过滤器拦截到对资源的访问时,如果处理之后放行过滤器,即调用FilterChain中的doFilter方法来放行过滤器. 接着才可以执行后面的资源
(3)如果后面仍然是过滤器,则也需要在过滤器的doFilter方法中调用FilterChain.doFilter方法才可以放行过滤器,执行后面的资源.
(4)如果后面没有过滤器,则访问对应的资源. 也就是说当所有的过滤器都调用了FilterChain的doFilter方法时,才可以放行所有的过滤器,才可以访问到对应的资源.
3.destroy方法
public void destroy()
-- 在Filter实例销毁之前,执行destroy方法进行善后的处理
4.过滤器的生命周期(了解)
当服务器启动时,web应用加载后会立即创建出当前web应用中的所有的Filter对象,创建出来后,立即调用init方法进行初始化出操作. 从此以后这个Filter对象一直驻留在服务器的内存中, 为后续所拦截的请求服务,每次过滤到对资源的访问时,都会执行doFilter这个方法进行拦截处理,直到服务器关闭或者web应用移出容器为止,随着web应用的销毁,过滤器实例也跟着销毁,在销毁之前会调用destroy方法执行善后的处理.
2.监听器
1.监听器概述
1.监听器概述
Listener也叫做监听器,是JavaWeb的三大组件之一。
所谓的监听器就是一个实现特定接口的java程序。这个程序专门用于监听另一个 java 对象状态变化(比如:对象的创建、销毁或属性改变等),当被监听对象发生上述事件后,就会通知监听器,监听器中的某个方法就会立即执行,来处理该事件。
1.监听器:
(1)事件源:按钮、车
(2)事件:按钮被点击、车被偷
(3)监听器:listener、警察
2.监听器的特点:
(1)通常是一个接口,其中的内容由我们开发人员来实现
(2)通常需要将监听器注册到事件源上
(3)监听器中的方法会在特定事件触发时执行.
2.监听器案例:按钮被点击
public static void main(String[] args) {
//1.创建一个窗口
JFrame frame = new JFrame();
//2.设置窗口的大小
frame.setSize(250, 200);
//3.设置窗口的位置
frame.setLocation(350, 250);
//4.创建一个按钮, 并添加到窗口中
JButton btn = new JButton("按钮");
/*
* 需求: 当按钮被点击时, 在控制台打印"hello btn~~!!"
* 事件源: 按钮
* 事件: 按钮被点击
* 监听器: 当把监听器注册到事件源开始, 监听器会一直
* 监听着事件源(按钮), 直到按钮被点击事件发生, 就会
* 激活监听器, 执行监听器中对应的方法, 从事实现特定功能
*/
//>>创建一个监听器(行为监听器)
ActionListener listener = new ActionListener() {
//处理事件的方法(事件处理器)
public void actionPerformed(ActionEvent e) {
String dateStr = new Date(e.getWhen()).toLocaleString();
System.out.println(dateStr);
System.out.println("hello btn~!!");
}
};
//>>将监听器注册到按钮上(此后监听器会一直监听按钮的状态)
btn.addActionListener(listener);
//5.将按钮添加到窗口中
frame.add(btn);
//6.设置窗口为显示状态
frame.setVisible(true);
System.out.println("执行完成...");
}
2.开发监听器
-
开发监听器的步骤
(1)写一个类(比如: MyServletContextListener),必须要实现对应的监听器接口(如: ServletcontextListener)
(2)在web应用的web.xml文件配置监听器完成注册
2.JavaWeb中的监听器
ServletContextListener:ServletContext对象的生命周期监听器,其中提供两个方法,一个是在ServletContext对象创建时调用,另一个是在ServletContext对象销毁时调用!
void contextInitialized(ServletContextEvent sce) 在创建ServletContext对象时调用
void contextDestroyed(ServletContextEvent sce) 在销毁ServletContext对象时地调用
3.监听器案例
写一个类实现ServletContextListener(生命周期监听器)接口,实现contextInitialized和contextDestroyed方法,查看ServletContext对象何时创建以及何时销毁。
(1)写一个类MyServletContextListener,实现ServletContextListener接口
(2)在web.xml中配置监听器完成注册.
(3)实现contextInitialized和contextDestroyed方法并测试访问。
补充:
01:jsp之九大内置对象与四大域对象()
一,什么是内置对象?
1、request对象
2、response对象
3、session对象
4、application对象
5、out 对象
6、pageContext 对象
7、config 对象
8、page 对象
9、exception 对象
对象名
|
功能
|
类型
|
作用域
| |
request
|
向客户端请求数据
|
javax.servlet.ServletRequest
|
Request
|
getAttributeNames() getCookies();
getParameter() getParameterValues();
setAttribute() getServletPath() …………..
|
response
|
封装了jsp产生的响应,然后被发送到客户端以响应客户的请求
|
javax.servlet.SrvletResponse
|
Page
|
addCookie() sendRedirect()
setContentType()
flushBuffer() getBufferSize() getOutputStream()
sendError() containsHeader()……………
|
pageContext
|
为JSP页面包装页面的上下文。管理对属于JSP中特殊可见部分中己经命名对象的该问
|
javax.servlet.jsp.PageContext
|
Page
|
forward() getAttribute()
getException() getRequest()
getResponse() getServletConfig()
getSession() getServletContext()
setAttribute()
removeAttribute() findAttribute() ……………
|
session
|
用来保存每个用户的信息,以便跟踪每个用户的操作状态
|
javax.servlet.http.HttpSession
|
Session
|
getAttribute(); getId();getAttributeNames();
getCreateTime();getMaxInactiveInterval();
invalidate();isNew();
|
application(
ServletContext
)
|
应用程序对象
|
javax.servlet.ServletContext
|
Application
| |
out
|
向客户端输出数据
|
javax.servlet.jsp.JspWriter
|
Page
|
print() println()
flush();
clear() isAutoFlush();
getBufferSize() close() …………
|
config
|
表示Servlet的配置,当一个Servlet初始化时,容器把某些信息通过此对象传递给这个Servlet
|
javax.servlet.ServletConfig
|
Page
|
getServletContext()
getServletName()
getInitParameter() getInitParameterNames()……………
|
page
|
Jsp实现类的实例,它是jsp本身,通过这个可以对它进行访问
|
javax.lang.Object
|
Page
|
flush()………
|
exception
|
反映运行的异常
|
javax.lang.Throwable
|
Page
|
getMessage();…………
|
二、四大作用域:
创建
|
销毁
|
域的作用范围
| ||
pageContext
|
从把变量放到pageContext开始
|
到jsp页面结束
|
只能在当前jsp页面使用
(当前页面)
|
page域
|
request
|
访问时创建
|
响应结束时销毁
|
只能在同一个请求中使用
(转发)
|
request域
|
Session
|
request.getSession()
|
1.超时销毁
2.调用session的invalidate
方法将会立即销毁session
3.当服务器非正常关闭
|
只能在同一个会话
(session对象
)
中使用 (私有的)
|
session域
|
application(ServletContext)
|
应用启动
|
应用结束
|
只能在同一个web应用中使用
(全局的)
|
context域
|
2.WEB阶段面试题汇总_1
-
-
描述Servlet调用过程
-
2.什么是数据库连接池及其工作原理
3.如何自己实现一个数据库连接池
2.中等
-
描述Servlet生命周期
2.什么是会话? Cookie和Session的工作原理
3.描述什么是过滤器及过滤器的作用
3.容易
-
描述HTTP协议的作用及具体内容(请求和响应的结构)