py-11-Servlet

目录:

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协议

  1. TOMCAT

    1. 服务器概述

      1. Servlet容器、WEB容器、服务器

Servlet容器:能够运行Servlet程序的环境就叫做Servlet容器

WEB容器:能够运行WEB应用程序的环境就叫做WEB容器

服务器:容器就是服务器。

2.tomcat下载和安装

2.下载

下载地址:Apache Tomcat® - Welcome!

       有解压版 和 安装版,还分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

  1. Servlet

    1. Servlet概述

      1. 什么是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

代表 Http 请求信息的对象
浏览器向服务器发送请求,服务器收到请求信息后,会在请求正式处理之前,创建代表请求的 Request 对象,将所有的请求信息封装在 Request 对象中。

1.1    Request继承关系

ServletRequest接口 -- 提供了一个request对象应该具有的功能
    |
    |-- HttpServletRequest接口,继承了ServletRequest接口,并添加了很多和HTTP协议相关的方法
   

1.2    Request功能

1.2.1    获取客户机基本信息、获取请求头信息

1 、获取客户机基本信息
(1) getRequestURL() -- 获取发送请求的完整URL
(2) getRequestURI() -- 获取请求行中的请求资源路径
(3) getRemoteAddr() -- 获取客户机的ip地址
(4) getMethod() -- 获取发送请求的方式
(5) getContextPath() -- 获取当前WEB应用的虚拟路径,在开发中,如果需要写当前WEB应用的虚拟路径,路径最好不要写死,而是通过getContextPath方法动态获取!
2 、获取请求头信息
(1) getHeader(String name) -- 根据请求头的名称获取指定的值

1.2.2    获取请求参数(!!)

1 、获取参数的方法
getParameter(String name) -- 通过请求参数的名称获取对应的参数值
getParameterValues(String name) -- 通过请求参数的名称获取对应的多个参数值组成的数组
getParameterMap() -- 获取所有请求参数组成的map集合
2 、请求参数乱码问题
问题描述:当浏览器向服务器发送请求参数时,如果请求参数中包含中文数据,服务器在获取时,会产生中文乱码问题!
问题产生的原因:
(1) 浏览器在发送请求参数时使用的码表 : utf-8,  因为浏览器在打开当前页面时使用什么编码 , 在发送参数时也会使用相同的码表来发送 .
(2) 服务器在解说请求参数时使用的码表 : iso8859-1,  如果没有指定服务器使用什么编码来接受数据 ,  服务器默认会使用 iso8859-1 来接受 .
由于两端使用的编码不一致 ,  所以造成了乱码 !
   解决方案一 :  使得两端使用的编码保持一直即可 !,  可以通过乱码产生的原理手动编码即可 !
String username = request
       .getParameter("username");
System.out.println("解决前,username: "+username);//乱码!!!
(1) 通过乱码字符串查询 iso8859-1 码表 ,  得到二进制数据
byte[] bytes = username.getBytes("iso8859-1");
(2) 将二进制数据通过查询 utf-8 得回正常的数据 .
username = new String(bytes, "utf-8");
System.out.println("解决后,username: "+username);
解决方案二 : 只对 POST 起作用
// 设置服务器接受请求实体内容数据的编码 ,  要放在任何获取参数的代码之前执行
request.setCharacterEncoding("utf-8");
String username = request
       .getParameter("username");
System.out.println("username: "+username);
注意: 上面这行代码只对 POST 提交的参数乱码问题起作用 .  因为这行代码是通知服务器使用 utf-8 来接受请求实体内容中的数据 ,  POST 提交的参数刚好在请求实体内容中 ,  所以可以起作用 !
但是 GET 提交的参数没有在请求实体中 ( 在请求行中 ),  因此这行代码对 GET 提交的参数乱码不起作用 !
总结 : 在开发中 , 如果要获取请求参数 ,  先观察浏览器发送请求参数的方式是不是 POST 提交 :
(1)  如果是 POST 提交 可以使用 request.setCharaterEncodign() 来解决
request.setCharaterEncodign();
     (2)  如果是 GET 提交 ,  可以使用手动编解码来解决乱码 !

1.2.3    实现请求转发(!!)

 
request.getRequestDispatcher (“demo.jsp"). forward(request, response);//转发到demo.jsp

1.2.4    作为域对象使用(!!)

域对象 : 如果一个对象 , 具有一个可以被看见的范围 , 利用这个对象上的 map 集合 , 可以在这个范围内 , 实现数据的共享 .
request 对象就是一个域对象 , request 上提供了很多操作自身 map 集合的方法
request.setAttribute(String name, Object value);// 存入一个属性 / 修改已有属性的值
request.getAttribute(String name); // 根据属性名获取对应的属性值
request.removeAttribute(String name);// 根据属性名删除对应的属性
request.getAttributeNames();// 获取域对象中所有属性的名字组成的枚举 .
生命周期 : 一次请求开始创建 request 对象 , 响应结束 request 对象就销毁了
作用范围 : 整个请求链中
主要功能 : 在整个范围内实现数据的共享 ( 带数据到目的地 )
需求 : 创建两个 Servlet: 分别是 RequestDemo6 RequestDemo7, RequestDemo6 中将请求转发给 RequestDemo7, 在转发时负责带参数到 RequestDemo7 中并接收打印在控制台上 .
  1. 创建两个 Servlet
2.在 RequestDemo6 中将请求转发给 RequestDemo7
3.在 RequestDemo6 负责将参数带给 RequestDemo7\
4.在 RequestDemo7 获取参数并打印在控制台上

1.实现请求包含

请求包含是服务器内部资源合并的效果
假设浏览器发送请求访问服务器中的 Aservlet, Aservlet 在处理请求的期间 , 发现自己不能够独立的处理这次请求 , 需要另外一个 Servlet 过来帮忙 , 这时可以在 Aservlet 中将 Bservlet 包含进来 , 然后由 Aservlet Bservlet 共同来处理这次请求 , Aservlet 处理的结果将会和 Bservlet 处理的结果合并在一起 , 一起响应给浏览器 .
实现请求包含 :
    request.getRequestDispatcher(“/Bservlet”).include(request, response);
示例 : 编写三个 Servlet, 分别为 Aservlet, Bservlet, Cservlet, 实现 Servlet 中的 doGet 方法来处理请求 , Bservlet 中将 Aservlet Cservlet 包含进来 , 共同来处理请求 .
  1. 创建三个 Servlet
2.编写三个 Servlet 中的 doGet 方法 , 处理请求
3.在 Bservlet 中将 Aservlet Cservlet 包含进来 .
4.测试 : 访问 Bservlet, 查询效果

1   Response

代表Http响应的对象

1.1 Response继承关系

ServletResponse接口  提供了一个Response对象应该具有的功能
       |
       |-- HttpServletResponse接口  继承了ServletResponse, 并且在此基础上添加了很多和Http协议相关的方法.

1.2 Response常用方法

状态行
HTTP/1.1 200 OK
  若干响应头
xxx: xxx
xxx: xxx
...
  响应实体内容
xxxxx
  设置状态码的方法:
setStatus()
  设置响应头的方法
setHeader()  
设置响应实体内容的方法
getOutputStream()
getWriter()

1.3 Response对象的功能

1.3.1    向客户端浏览器发送数据

getOutputStream
getWriter
1getOutputStream(字节流)
//>>向外发送数据(英文)
response.getOutputStream().write( "Hello response!".getBytes());
//>>向外发送中文数据
//getBytes方法默认使用GBK来发送数据。
response.getOutputStream().write(
       "哈喽 response!".getBytes());
 
字节流在发送中文数据的乱码问题:
原因:(1) 在服务端通过getBytes()方法将字符串转换成二进制数据再发送给浏览器,此时默认的编码是系统平台码,也就是GBK
(2)浏览器在接收数据时,如果使用编码不是GBK,两端编码不一致就会出现乱码问题。
解决:保证编码时和解码时使用的码表是一致的!由于在开发中我们使用最多的码表是utf-8, 因此我们应该保证使用utf-8来发送数据, 也保证浏览器使用utf-8来接收数据!
//指定浏览器在接收数据时也使用utf-8
response.setContentType(
       "text/html;charset=utf-8");    
 
//指定在服务端使用utf-8来发送数据(getBytes方法默认使用GBK来发送数据。)
response.getOutputStream().write(
       "哈喽 response!".getBytes("utf-8"));  
2getWriter(字节流)
在通过字符流发送数据时,底层也是要转成字节再发送,如果不指定,服务器默认使用的编码为iso8859-1, 这个码表中没有中文数据,所以在发送中文数据时,不管浏览器使用什么编码来接收,都会出现乱码问题。
解决:(1)指定服务器端在发送数据时使用utf-8编码,再指定浏览器在接收时也使用相同的码表即可!
//(1)指定服务端发送数据使用utf-8
response.setCharacterEncoding("utf-8");
//(2)指定浏览器接收数据也是用utf-8
response.setContentType(
       "text/html;charset=utf-8");
 
response.getWriter().write("哈喽 reponse!");
  在实际开发中,我们只需要通过response.setContentType("text/html;charset=utf-8")这行代码就可以解决字符流在发送中文数据时的乱码问题。
/* 这行代码既会通知服务器使用utf-8发送数据,
 * 也会通知浏览器使用utf-8来接收数据 */
response.setContentType(
       "text/html;charset=utf-8");
response.getWriter().write("哈喽 reponse!");
 
总结:不管是字节流还是字符流,在发送数据时如果出现了乱码问题,都可以使用response.setContentType("text/html;charset=utf-8")这行代码来解决:
字节流:
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)getOutputStreamgetWriter这两个方法不能同时使用(出现), 因为这两个方法是互斥的!
(2)getOutputStreamgetWriter这两个方法可以获取能够像浏览器发送数据的流, 这两个流不是指向浏览器客户端,而是指向response缓冲区. 等请求结束后, 请求会再次回到服务器,服务器会从response对象获取到数据, 组织成响应消息在发送给浏览器.
(3)getOutputStreamgetWriter这两个方法获取到的流, 使用完之后不需要关闭,因为浏览器会帮我们关闭!

1.3.2    实现请求重定向

可以实现资源的跳转, 既可以是服务器内部同一个WEB应用内的资源之间的跳转, 也可以是不同的WEB应用或者是不同的服务器之间的资源跳转.
实现代码:
    response.setStatus(302);
    response.setHeader("location", "url地址");
    上面的两行代码可以简化为:
    response.sendRedirect("uri地址");
  重定向的特点:
(1)两次请求,两次响应
(2)地址栏地址会发生变化
(3)request对象不是同一个
(4)既可以实现在同一个WEB应用内部的资源之间进行跳转, 也可以实现在不同的WEB应用或者是不同的服务器内部的资源之间进行跳转
例如:
response.sendRedirect("/day14/param.html");
 
response.sendRedirect("http://tmooc.cn");

1.3.3    实现定时刷新

通过refresh响应头可以实现在多少秒之后跳转到指定的资源.
代码实现:
//提示用户注册成功, 3秒之后将会跳转到主页
//>>处理响应正文乱码
response.setContentType(
       "text/html;charset=utf-8");
 
response.getWriter().write("恭喜您注册成"
       + "! 3秒之后将会跳转到主页...");
 
//实现3秒之后刷新到主页
response.setHeader("refresh",
       "3;url=/day15/index.html");
 
定时刷新的特点:
(1)两次请求, 两次响应
(2)地址栏地址会发生变化
(3)request对象不是同一个
(4)既可以实现在不同的WEB应用或者不同的主机之间进行跳转, 也可以实现在同一个WEB应用内的资源之间进行跳转
(5)和重定向不同的是, 定时刷新可以实现在多少秒之后再进行跳转, 而重定向是立即跳转!
 

1.4 三种资源跳转方式的区别和使用场景

  1. 三种资源跳转方式的区别

1、请求转发
    

 1)一次请求,一次响应(request对象是同一个)

2)地址栏地址不会发生变化
3)转发只能在同一个WEB应用内部的资源之间进行跳转,不能在不同的WEB应用或者是不同的虚拟主机之间进行跳转。否则将会提示找不到资源.

2、重定向
1)两次请求,两次响应(request对象不是同一个)
2)地址栏地址会发生变化
3)既可以在同一个WEB应用内部的资源之间进行跳转,也可以在不同的WEB应用或者是不同的虚拟主机之间进行跳转,如下:
3、定时刷新
1)两次请求,两次响应(request对象不是同一个)
2)地址栏地址会发生变化
3)既可以在同一个WEB应用内部的资源之间进行跳转,也可以在不同的WEB应用或者是不同的虚拟主机之间进行跳转,如下:

 4)定时刷新和重定向主要的区别在于,重定向是立即跳转,而定时刷新是在指定多少秒之后立即跳转,并且在跳转之前,可以向浏览器发送响应数据并维系一段时间.

2.三种资源跳转方式的使用场景

1、如果是同一个WEB应用内部资源的跳转,三种方式都可以,具体使用哪一种:
1)如果希望在跳转之后地址栏地址不会发生变化,这里只能使用请求转发
2)如果希望在跳转之后地址栏地址会发生变化,这里可以使用重定向或定时刷新
3)如果在跳转的过程中,希望带数据到目的地,这里只能使用请求转发
4)如果没有什么特别的需求,仅仅是做一个跳转,推荐使用转发. 因为转发是一次请求,可以减少访问服务器的次数,减少服务器的压力!
  2、如果是不同的WEB应用之间资源的跳转,只能使用重定向和定时刷新,具体使用哪一种:
重定向是立即跳转,中间没有间隔,而定时刷新可以指定多少秒之后再进行跳转,在跳转之前,还可以发送响应到客户端,并维系一段时间.
1)因此如果需要指定多少时间之后再跳转可以使用定时刷新,如果在跳转之前,需要提示用户,可以使用定时刷新.

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对象

代表整个WEB应用的对象
服务器启动并加载WEB应用之后,立即创建代表当前WEB应用的ServletContext对象。创建之后该对象会一直驻留在服务器的内存中,唯一的代表当前WEB应用。直到服务器关闭,或者是WEB应用被移出容器,随着WEB应用的销毁,ServletContext对象也会跟着销毁。

2.2 获取ServletContext对象

servlet中提供了一个方法,getServletContet(),可以直接获取ServletContext对象。
ServletContext context = this.getServletContext();

2.3 作为域对象使用

2.3.1    作为域对象使用

1、域对象提供的方法
setAttribute(String name, Object value) -- ServletContext域中添加一个域属性.
getAttribute(String name) -- 通过属性名称获取指定名称的属性
removeAttribute(String name) -- 通过属性名称删除指定名称的属性
getAttributeNames() -- 获取所有属性名称组成的枚举
  2、域对象的特征:
(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

  1. 会话技术

    1. 会话技术概述

      1. 什么是会话?

为了实现某一个功能,浏览器和服务器之间可能会产生多次的请求和响应,从浏览器访问服务器开始,到访问服务器结束,关闭浏览器为止,这期间产生的多次请求和响应加在一起,就称之为浏览器和服务器之间的一次会话。

2.如何保存会话中产生的数据?

在这里我们可以尝试使用之前学习过的两个域对象:request和ServletContext对象,但是

request域太小了

ServletContext域太大了

我们可以使用会话技术中的两门技术,分别是Cookie和Session

2.Cookie

  1. 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

  1. 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);
5.总结: Cookie和session区别
(1)Cookie是将会话中产生的数据保存在客户端, 是客户端技术
(2)session是将会话中产生的数据保存在服务器端, 是服务器端技术
(3)Cookie是将数据保存在客户端, 相比不安全, 容易被人获取, 并且也相对不稳定, 容易丢失或意外删除. 优点是Cookie可以长时间保存而且不占用服务器的空间, 因此Cookie适合保存对安全性要求不高, 但是需要长时间保存的数据.
(4)session是将数据保存在服务器端, 相比更安全, 并且也更稳定, 但是session会占用服务器的空间, 保存时间不能太长. 因此session适合保存对安全性要求较高, 但是不需要长时间保存的数据.

day07

  1. JSP

    1. JSP 概述
      1. JSP介绍

SUN 公司提供的动态 web 资源的开发技术,看起来非常像 html ,但是可以在 JSP 页面中写 java 代码,所以 JSP 是一种动态 web 资源开发技术 .
JSP 本质上就是一个 Servlet!

2.JSP技术的由来

JSP 的出现是为了解决 Servlet 在响应时不适合向外输出页面的问题
1 Servlet 本质上是一段 java 代码,非常适合处理逻辑,但是处理的结果不太适合由 Servlet向外输出(不适合输出完整的html页面)。
2 HTML 是用于开发网页的一门技术,可以用来展示数据。但是 HTML 开发出来的页面本质上就是一个文档 ( 静态资源 ) ,无法展示动态的数据。
3 JSP 非常适合编写 HTML 代码,适合作为响应页面向外输出,同时 JSP 里可以写 java 代码,也可以展示动态的数据。
4 所以 JSP 的出现既可以解决 Servlet不适合向外响应一个完整的页面又可以解决html 无法展示动态数据的问题
5 JSP 在第一次访问时,会被翻译成一个 Servlet ,对 JSP 访问后看到的页面 其实就是翻译后的 Servlet 在向外输出!
作者(靳烨)的jsp翻译成servlet在以下文件中;
G:\Tomcat\apache-tomcat-7.0.67\apache-tomcat-7.0.67\work\Catalina\localhost\day17-servlet-06-jsp

3.修改JSP模版

修改 JSP 模版步骤 : 点击菜单栏中的 window --> Preferences ,出现如下窗口 :
点击 edit 编辑 JSP 模版,修改为如下 :
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
</head>
<body>
${cursor}
</body>
</html>

2.JSP语法

  1. 模版元素

直接写在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运行环境的对象

  1. 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代码。

  1. EL表达式

EL表达式在JSP中可以非常方便的获取数据,可以代替JSP页面中的JSP表达式(<%=  %>)

基本结构: ${ 表达式 }

EL只能获取不能设置!!!

EL只能获取不能遍历!!!

EL表达式提供了如下功能:

(1)EL可以获取常量/变量(必须存入域中)/表达式的值

(2)EL可以获取域中的数组或集合中的数据

获取域中集合中的数据和获取数组的方式相同. 这里不再举例

(3)EL可以获取域中的Map集合中的数据。

2.JSTL标签库

jstl包:

文件寻贴主得

 JSTL标签库是为JavaWeb开发人员提供的一套标准通用的标签库,JSTL标签库和EL配合使用取代JSP中大部分的Java代码.

在使用 JSTL 标签库提供的标签之前,必须在 JSP 中通过 taglib 指令引入 JSTL 标签库 ( 如果缺少 JSTL 库相关的 jar ,还需要提前导入 jar )
1 、导入 JSTL jar
2 、引入 JSTL
<%@ taglib uri="Oracle Java Technologies | Oracle" prefix="c" %>
其中常用的标签如下 :
1 <c:set></c:set> -- 往四大作用域中添加域属性,或者修改四大作用域中已有的属性
1 )往四大作用域中添加一个域属性
2 )修改四大作用域中已有的属性
如果重复添加相同的属性,值会发生覆盖,相当于修改 .
3 )修改作用域中 Map 集合中的属性
c_set 标签属性总结 :
(1)var – 指定存入域中属性的名称
(2)value -- 指定存入域中属性的值
(3)scope – 指定将属性如此哪一个域中
(4)target – 指定修改域中的哪一个集合,比如:<c:set target="${map}"...
(5)property – 指定修改域中集合中的哪一个属性
2 <c:if></c:if> -- 构造 if…else… 语句
<c:if test="${3>5}">yes</c:if>
<c:if test="${!(3>5)}">no</c:if>
test 属性用于指定判断的条件,注意 :JSTL 中没有提供 else 对应的标签
3 <c:forEach></c:forEach> -- 对集合或数组等中元素进行循环遍历或者是执行指定次数的循环 .
1 )遍历域中数组或集合中的元素
2 )遍历域中 map 集合中的元素
注:
  EL表达式中只认识pageContext隐式对象,但是通过pageContext对象可以获取其他的九大内置对象。
${pageContext.getRequest().getContextPath()}
或:
${pageContext.request.contextPath}
(3 )打印 1~100 之间的奇数,并指定间隔符号
4 )                                                                                                                                                                                                                                                                                                                                                                   
c_forEach 标签属性总结 :
(1)items: 指定需要遍历的集合或数组
(2)var: 指定用于接收遍历过程中的元素
(3)begin: 指定循环从哪儿开始
(4)end: 指定循环到哪儿结束
(5)step: 指定循环时的步长
(6)varStatus="status" 返回一个表示循环状态的对象,该对象还具有如下属性:
a)count:表示当前遍历的元素是第几个 b)first:表示当前遍历的元素是否为第一个
c)last:表示当前遍历的元素是否为最后一个 d)index:表示当前遍历元素的索引(从零开始)

day08

  1. 过滤器

    1. 过滤器概述

      1. 什么是过滤器?

Servlet技术规范中,定义了Servlet、Filter、Listener三门技术, 其中Filter也叫做过滤器,通过过滤器技术,开发人员可以实现用户在访问某个资源之前或之后,对访问的请求和响应进行拦截,从而做一些相关的处理。

总结:

1.所谓的过滤器,就是拦截用户对资源的访问

2.一个过滤器可以拦截多个资源,一个资源也可以配置多个过滤器进行拦截

3.其实所谓的拦截,就是将代表请求的request对象和代表响应的response对象拦截下来,拦截下来后:

(1)控制是否允许访问 – 比如:用户登陆之后才能访问自己的订单或购物车

(2)在访问资源之前或之后做一些处理 比如: 全站乱码解决

2.开发过滤器

  1. 开发过滤器的步骤

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.过滤器中的方法

  1. 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. 开发监听器的步骤

(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之九大内置对象与四大域对象()

一,什么是内置对象?

在jsp开发中会频繁使用到一些对象,如ServletContext HttpSession PageContext等.如果每次我们在jsp页面中需要使用这些对象都要自己亲自动手创建就会特别的繁琐.SUN公司因此在设计jsp时,在jsp页面加载完毕之后自动帮开发者创建好了这些对象,开发者只需要使用相应的对象调用相应的方法即可.这些系统创建好的对象就叫做内置对象.
在servlet程序中,如果开发者希望使用session对象,必须通过request.getSession()来得到session对象;而在jsp程序中,开发中可直接使用session(系统帮我们创建好的session对象的名字就叫session)调用相应的方法即可,如:session.getId().
   JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception
内置对象(又叫隐含对象)特点: 
1. 由JSP规范提供,不用编写者实例化。 
2. 通过Web容器实现和管理 
3. 所有JSP页面均可使用 
4. 只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%>或<%使用内置对象%>)

1、request对象

request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。

2、response对象

response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。

3、session对象

session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。

4、application对象

 application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

5、out 对象

out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。

6、pageContext 对象

pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。

7、config 对象

config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。

8、page 对象

page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。

9、exception 对象

exception 对象的作用是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 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

    1. 描述Servlet调用过程

1 )浏览器向服务器发送请求(例如地址为: http://localhost/day13/TestServlet
2 )服务端通过请求解析出浏览器访问的是哪一台主机(例如: localhost
3 服务端通过请求解析出浏览器访问的是哪一个 WEB 应用(例如: /day13
4 )再通过请求解析出浏览器访问的是哪一个资源(例如: /TestServlet
5 )如果该 Servlet 是第一次被访问,服务器会加载 Servlet 类,并创建该类的实例 .
6 )调用 Servlet init 方法进行初始化操作 .
7 在处理请求之前,创建代表请求的 request 对象和代表响应的 response 对象,传递给 service 方法。
8 )调用 Servlet service 方法处理请求。将需要响应的数据写入 response 对象中
9 )服务器取出 response 中保存的数据,按照 Http 协议的格式发送给浏览器,响应完毕 !

2.什么是数据库连接池及其工作原理

1 )什么是数据库连接池?
所谓的池就是程序中用来共享资源的容器,比如线程池,常量池,而数据库连接池就是用来存放连接的容器,将连接存放在容器中,在整个程序中共享。
2 )连接池的工作原理 / 为什么要使用连接池
通过传统 JDBC 操作数据库,需要连接时就创建一个连接使用,用完后将连接直接关闭还给数据库。当并发访问的用户非常多时,这种频繁开关连接的操作将会十分的耗费资源,并且效率低下。
因此我们可以在程序中创建一个连接池,当程序启动时就初始化一批连接放在池中供整个程序共享。当需要连接时从连接池中获取一个连接进行使用,当用完连接后将连接还回连接池中。这样可以减少连接开关的次数,也可以实现连接的复用,从而提高程序执行的效率。

3.如何自己实现一个数据库连接池 

SUN 公司为实现连接池提供了一个接口 : javax.sql.DataSource, 要求所有的连接池必须实现这个接口
实现数据库连接池的步骤
1 、写一个类,实现 DataSource 接口
2 、在实现类中,创建一个容器 (LinkedList) ,当作连接池使用
3 、在静态代码块中,初始化一批连接放在连接池中
4 、实现 getConnection 方法,方便获取连接
5 、添加自定义方法 returnConn ,用于将连接还回连接池中
6 、写测试类测试自定义连接池

2.中等

  1. 描述Servlet生命周期

Servlet 在第一次被访问时创建 Servlet 实例,创建之后服务器会立即调用 init 方法进行初始化的操作,创建之后, Servlet 实例会一直驻留在服务器的内存中,为后续的请求服务 . 只要有请求来访问这个 Servlet ,服务器就会调用 service 方法来处理请求,直到服务器关闭,或者 WEB 应用被移出容器,随着 WEB 应用的销毁, Servlet 实例也会跟着销毁,在销毁之前服务器会调用 destroy 方法进行善后的处理。
试着用自己的话描述

2.什么是会话? CookieSession的工作原理

1 )将浏览器和服务器之间的多次请求和响应加在一起就可以看作浏览器和服务器之间的一次会话。
2 Cookie 的工作原理:
客户端向服务器发送请求,服务器获取需要保存的数据,并将需要保存的数据通过 Set-Cookie 响应头发送给浏览器,浏览器会以 Cookie 的形式保存在浏览器的内部 .
当客户端再次发送请求访问服务器,服务器可以通过 Cookie 请求头获取上次发送给浏览器的 Cookie 信息,通过这种方式可以保存会话中产生的数据 .
3 Session 的工作原理 :
浏览器第一次发送请求需要保存数据时 , 服务端获取到需要保存的数据,去服务器内部检查一下有没有为当前浏览器服务的 session ,如果有就直接拿过来用,如果没有 session 就创建一个新的 session 拿过来用 . 接着将数据保存在 Session 中,做出响应
当浏览器再去访问服务器时,服务器可以从 session 中获取到之前为当前浏览器保存的数据,通过这种方式,也可以来保存会话中产生的数据!

3.描述什么是过滤器及过滤器的作用

过滤器也叫做 Filter ,是 JavaWeb 的三大组件之一。可以拦截用户对资源的访问。
所谓的拦截其实就是将代表请求的 request 对象和代表响应的 response 对象拦截下来。
通过过滤器可以实现在用户访问某个资源之前或者之后,对访问的请求和响应进行拦截,从而做一些相关的处理。比如:根据用户登录与否控制是否允许访问或全站乱码处理或异常处理等

3.容易

  1. 描述HTTP协议的作用及具体内容(请求和响应的结构)

1 Http 协议的作用:用来规定浏览器客户端和服务器之间通信的格式。规定了浏览器在发送请求时该符合什么的格式,在做出响应时该符合什么的格式。
2 HTTP 协议的内容: HTTP 请求(请求行、若干请求头、请求实体内容)、 HTTP 响应(状态行、若干响应头、响应实体内容)

2.描述四大域对象的特征

1 PageContext
1 )生命周期:开始访问 JSP 页面时创建 PageContext 对象,访问 JSP 页面结束时销毁 PageContext 对象
2 )作用范围:在整个 JSP 页面中
3 )主要功能:在整个 JSP 页面中实现数据的共享。
2 request
1 )生命周期:一次请求开始时创建 request 对象,一次请求结束时销毁 request 对象。
2 )作用范围:在整个请求链中
3 )主要功能:在整个请求链中实现数据的共享
3 session
1 )生命周期:
创建 : 当第一次调用 request.getSession() 方法时将会创建 session 对象 .
销毁: session 分为三种情况 :
a) 超时销毁 : 如果超过 30 分钟不操作 session, session 将会超时销毁 .
b) 自杀 : 当调用 session.invalidate() 方法时会立即销毁 session
c) 意外身亡 : 当服务器非正常关闭时 , session 会销毁 ! 当服务器正常关闭时 , session 将会以文件的形式保存在 tomcat 服务器 work 目录下
2 )作用范围:在整个会话范围内
3 )主要功能:在整个会话范围内实现数据的共享
4 ServletContext
1 )生命周期:服务器启动 WEB 应用被加载之后立即创建 ServletContext 对象,服务器关闭或 WEB 应用被移出容器,销毁 ServletContext 对象。
2 )作用范围:在整个 WEB 应用中
3 )主要功能:在整个 WEB 应用范围内实现数据的共享

3.JSP的九大隐式对象是哪九个?

page requeset response application ServletContext )、 config ServletConfig )、 session HttpSession )、 exception out pageContext

思维导图


作者:Darren

QQ:603026148

以上内容归Darren所有,如果有什么错误或者不足的地方请联系我,希望我们共同进步。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从码农到码到成功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值