定义:
jsp 本质上就是一个 Servlet,它是 Servlet 的一种特殊形式(由 SUN 公司推出),每个 jsp 页面都是一个 servlet实例。
Servlet 是由 Java 提供用于开发 web 服务器应用程序的一个组件,运行在服务端,由 servlet 容器管理,用来生成动态内容。
一个 servlet 实例是实现了特殊接口 Servlet 的 Java 类,所有自定义的 servlet 均必须实现 Servlet 接口。
区别:
jsp 是 html 页面中内嵌的 Java 代码,侧重页面显示。
Servlet 是 html 代码和 Java 代码分离,侧重逻辑控制,mvc 设计思想中 jsp 位于视图层,servlet
位于控制层。
Jsp 运行机制:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YhdourWP-1658820433400)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml10076\wps1.jpg)]](https://1000bd.com/contentImg/2022/07/30/091926942.png)
JVM 只能识别 Java 类,并不能识别 jsp 代码;
web 容器收到以.jsp 为扩展名的 url 请求时,会将访问请求交给tomcat 中 jsp 引擎处理,每个 jsp
页面第一次被访问时,jsp 引擎将 jsp 代码解释为一个 servlet 源程序,接着编译servlet 源程序生成.class
文件,再由web 容器 servlet 引擎去装载执行 servlet 程序,实现页面交互
| 对象名 | 功能 | 作用域 |
|---|---|---|
| request | 向客户端请求数据 | Request |
| response | 封装了jsp产生的响应,然后被发送到客户端以响应客户的请求 | Page |
| pageContext | 为JSP页面包装页面的上下文。管理对属于JSP中特殊可见部分中己经命名对象的该问 | Page |
| session | 用来保存每个用户的信息,以便跟踪每个用户的操作状态 | Session |
| application | 应用程序对象 | Application |
| out | 向客户端输出数据 | Page |
| config | 表示Servlet的配置,当一个Servlet初始化时,容器把某些信息通过此对象传递给这个Servlet | Page |
| page | Jsp实现类的实例,它是jsp本身,通过这个可以对它进行访问 | Page |
| exception | 反映运行的异常 | Page |
<%…%>用于在JSP页面中嵌入Java脚本
<%!…%>用于在JSP页面中申明变量或方法,可以在该页面中的<%…%>脚本中调用,声明的变量相当于Servlet中的定义的成员变量。
区别:
forward是把另一个页面加载到本页面,不改变浏览器的路径
redirect是跳转到另一个页面,会改变浏览器的路径
实现方式:
重定向: response.sendRedirect(“重定向的路径”)
转发: request.getRequestDispatcher(“转发路径”).forward(request, response);
1.JSP与Java Servlet一样,是在服务器端执行的,通常返回该客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览
2.在大多数Browser/Server结构的Web应用中,浏览器直接通过HTML或者JSP的形式与用户交互,响应用户的请求
3.JSP在服务器上执行,并将执行结果输出到客户端浏览器,我们可以说基本上与浏览器无关
Servlet处于服务器进程中,只会有一个servlet实例,每个请求都会产生一个新的线程,而且servlet实例一般不会销毁
CGI:来一个请求就创建一个进程,用完就销毁,效率低于servlet
<%@ page session=“false” %>
当客户端向一个jsp页面发送请求时,Web Container将jsp转化成servlet的源代码(只在第一次请求时),然后编译转化后的servlet并加载到内存中执行,执行的结果response到客户端
jsp只在第一次执行的时候会转化成servlet,以后每次执行,web容器都是直接执行编译后的servlet,所以jsp和servlet只是在第一次执行的时候不一样,jsp慢一点,以后的执行都是相同的。
Session代表者服务器和客户端一次会话的过程。Session对象存储特定用户会话所需要的属性和配置信息,这样当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失。而是在整个用户会话中一直存活下去。当客户端关闭会话,或者Session超时失效会话结束。
HTTP Cookie(Web Cookie或者浏览器Cookie)是服务器发送到浏览器并保存在本地的一小块数据,他会在浏览器下次向同一个服务器再次发起请求时被携带并发送到服务器上。通常Cookie用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
Cookie:
是web服务器发送给浏览器的一块信息,浏览器会在本地文件一个文件中给每个web服务器存储cookie。以后浏览器再给特定的web服务器发送请求时,同时会发送所有为该服务器存储的cookie。
Session:
是存储在web服务器端的一块信息。session对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失。而是在整个用户会话中一直存在下去。
区别:
存在的位置
cookie存在于客户端,临时文件夹中;
session存在于服务器的内存中,一个session域对象为一个用户浏览器服务。
安全性
cookie是以明文的方式存放在客户端的,安全性低,可以通过一个加密算法进行加密后存放。session本身存放于服务器的内存中,所以安全性好。
网络传输量
cookie会传递消息给服务器
session本身存放于服务器,不会传送流量
生命周期(以30分钟为例)
cookie的生命周期是累计的,从创建时,就开始计时,30分钟后,cookie生命周期结束;
session的生命周期是间隔的,从创建时,开始计时如在30钟后,没有访问session,那么session生命周期被销毁,但是,如果在30分钟内(如在29分钟时)访问过session,那么,将重新计算session的生命周期;关机会造成session周期的结束,但是对cookie没有影响。
访问范围
cookie为多个用户浏览器共享;
session为一个用户浏览器独享
简单来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。
当用户在某个网站注册后,就会收到一个唯一用户ID的cookie。客户后来重新连接时,这个用户ID会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。
1、调用request.getCookie
2、对数组进行循环,调用每个cookie的getName方法
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识,称为session id;如果已经包含一个session id则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。
如果客户请求不包含session id,则为此客户创建一个session并且生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存。
Cookie的过期和Session的超时(过期),都是对某个对象设置一个时间,然后采用轮训机制(或者首次访问时)检查当前对象是否超时(当前对象会保存一个开始时间),如果超时则进行移除。
cookie保存在浏览器中,不安全。而session是保存在服务端的。cookie的生命周期很长,而session很短,一般也就几十分钟。
cookie是保存在客户端,session保存在服务器端,cookie保存着session相关信息。
如果cookie没有超时,那么浏览器每次请求都会带上该cookie信息,服务器端根据cookie信息从session缓存中获取相对应的session。这两个信息有一个超时,用户连接即宣告关闭。
会话的超时由服务器来维护,它不同于Cookie的失效日期。
首先,会话一般基于驻留内存的cookie,不是持续性的cookie,因而也就没有截至日期。
即使截取到JSESSIONID cookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。
Nginx ip_hash策略 ,服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。
Session 复制,任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。
共享 Session,服务端无状态话,将用户的 Session 等信息使用缓存中间件来统一管理,保障分发到每一个服务器的响应结果都一致。
单点登录的原理是后端生成一个 session ID,然后设置到 cookie,后面的所有请求浏览器都会带上 cookie,然后服务端从 cookie 里获取 session ID,再查询到用户信息。所以,保持登录的关键不是 cookie,而是通过cookie 保存和传输的 session ID,其本质是能获取用户信息的数据。除了 cookie,还通常使用 HTTP 请求头来传输。但是这个请求头浏览器不会像 cookie 一样自动携带,需要手工处理。
session在下列情况下被删除:
程序调用HttpSession.invalidate()
距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
服务器进程被停止
注意关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,不会使服务器端的session对象失效。
GET
get重点是从服务器上获取资源
get传输数据是通过URL请求,以field(字段)=value的形式,置于URL后,并且用“?”连接,多个请求数据用“&”连接。
get传输数据量小,因为受URL长度限制,但是效率高。
get是不安全的,因为URL是可见的,可能会泄露信息。
get方式只能支持ASCII字符,向服务器传的中文可能会乱码。
POST
post重点是想服务器发送数据
post传输通过HTTP的post机制,将字段和对应值封存在请求实体中发送个服务器。这个过程用户时不可见的。
post可以传输大量数据,所以上传文件时只能用post
post支持标准字符集,可以正确的传递中文字符
post比get安全性高
1XX:指信息-表示请求已接收,继续处理
2XX:成功-表示请求已被接收、理解、处理
3XX:重定向-要完成请求必须进行更进一步的操作
4XX:客户端错误-请求有语法错误或请求无法实现
5XX:服务端错误-服务端未能实现合法的请求
200:请求被正常处理
204:请求被受理但没有资源可以返回
206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。
301:永久性重定向
302:临时重定向
303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上
304:发送附带条件的请求时,条件不满足时返回,与重定向无关
307:临时重定向,与302类似,只是强制要求使用POST方法
400:请求报文语法有误,服务器无法识别
401:请求需要认证
403:请求的对应资源禁止被访问
404:服务器无法找到对应资源
500:服务器内部错误
503:服务器正忙
本质区别
转发是服务器行为
重定向是客户端行为
重定向特点:两次请求,浏览器地址发生变化,可以访问自己web之外的资源,传输的数据会丢失。
请求转发特点:一次请求,浏览器地址不变,访问的是自己本身的web资源,传输的数据不会丢失。
HTTPS = HTTP + SSL;
https有ca证书,Http一般没有
http是超文本传输协议,信息是明文传输。HTTPS则是具有安全性的SSL加密传输协议
http默认80端口,HTTPS默认443端口
二进制协议代替文本协议,更加简洁高效
针对每个域只使用一个多路复用的连接
压缩头部信息减小开销
允许服务器主动推送应答到客户端的缓存中
请求报文
请求行:包含请求方法、URL、HTTP版本信息
请求首部字段
请求内容实体
响应报文
状态行:包含HTTP版本、状态码、状态码的原因短语
响应首部字段
响应内容实体
无状态协议对于事物处理没有记忆能力。缺少状态意味着后续处理需要前面的信息
通过cookie和session解决
客户使用HTTPS的URL访问web服务器,要求与web服务器建立SSL连接
web服务器收到客户端请求后,将网站的证书信息(证书中包含公钥)传送一份给客户端
客户端的浏览器与web服务器开始协商SSL连接的安全等级,也就是信息的加密等级
客户端的浏览器根据双方同意的安全等级,建立会话秘钥,然后利用网站的公钥将会话秘钥加密,并传送给网站
web服务器利用自己的私钥解密出会话秘钥
web服务器利用会话秘钥加密与客户端之间的通信
通用首部字段(请求报文与响应报文都会使用的首部字段)
Date:创建报文时间
Connection:连接的管理
Cache-Control:缓存的控制
Transfer-Encoding:报文主体的传输编码方式
请求首部字段(请求报文会使用的首部字段)
Host:请求资源所在服务器
Accept:可处理的媒体类型
Accept-Charset:可接收的字符集
Accept-Encoding:可接受的内容编码
Accept-Language:可接受的自然语言
响应首部字段(响应报文会使用的首部字段)
Accept-Ranges:可接受的字节范围
Location:令客户端重新定向到的URI
Server:HTTP服务器的安装信息
实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)
Allow:资源可支持的HTTP方法
Content-Type:实体主类的类型
Content-Encoding:实体主体适用的编码方式
Content-Language:实体主体的自然语言
Content-Length:实体主体的的字节数
Content-Range:实体主体的位置范围,一般用于发出部分请求时使用
**TCP(Transmission Control Protocol,传输控制协议)**是基于连接的协议,就是,在正式连接收发数据之前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次对话才能建立起来
**UDP(User Data Protocal,用户数据报协议)**是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接。而是直接就把数据包发送过去!UDP适用于一次只传送少量数据,对可靠性要求不高的应用环境。
三次握手(若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TdfQ01yf-1658820433401)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml10076\wps2.jpg)]](https://1000bd.com/contentImg/2022/07/30/091927068.png)
为了准确无误的把数据送达目标处,TCP协议采用了三次握手策略。
用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,它一定向对方确认是否成功送达。握手过程过程中使用了TCP的标志:SYN和ACK
发送端首先发送一个带SYN标志的数据包给对方
接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息
最后,发送再回传一个带ACK的标志的数据包,代表“握手”结束。
四次挥手(断开一个TCP连接需要四次挥手)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-APxlfN37-1658820433401)(file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml10076\wps3.jpg)]](https://1000bd.com/contentImg/2022/07/30/091927491.png)
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手
JDBC 的全称是(Java Database Connection),也就是Java数据库连接,可以用来操作关系型数据库。
JDBC接口及相关类在Java.sql包和javax.sql包里。可以用来连接数据库,执行SQL查询,存储过程,并处理返回结果。
Class.forName()加载数据库连接驱动;
DriverManager.getConnection()获取数据连接对象;
根据 SQL 获取 sql 会话对象,有 2 种方式 Statement、PreparedStatement ;
执行 SQL 处理结果集,执行 SQL 前如果有参数值就设置参数值 setXXX();
关闭结果集、关闭会话、关闭连接。
PreparedStatement 继承于 Statement,PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。
作为Statement的子类 , PreparedStatement 继承了 Statement 的所有功能 。三 种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数
Statement 一般用于执行固定的没有参数的SQL
PreparedStatement 一般用于执行有 ?参数预编译的SQL语句。
PreparedStatement支持?操作参数,相对于Statement更加灵活。
PreparedStatement可以防止SQL注入,安全性高于Statement。
①代码的可读性和可维护性.Statement 需要不断地拼接,而 PreparedStatement 不会。
②PreparedStatement 尽最大可能提高性能.DB 有缓存机制,相同的预编译语句再次被调用不会再次需要编译。
③最重要的一点是极大地提高了安全性.Statement 容易被 SQL 注入,而PreparedStatementc 传入的内容不会和 sql 语句发生任何匹配关系。
前提:为数据库连接建立一个缓冲池。
从数据池获取创建可用连接。
使用完毕之后,把连接返回给连接池
在系统关闭前,断开所有连接并释放连接占用的系统资源
能够处理无效连接,限制连接池中的连接总数不低于或者不超过某个限定值
通过制定接口,数据库厂商来实现。我们只要通过接口调用即可。
驱动只有在通过的Class.forName反射机制来加载的时候才会出现。
共有三种ResultSet对象。
ResultSet.TYPE_FORWARD_ONLY:这是默认的类型,它的游标只能往下移。
ResultSet.TYPE_SCROLL_INSENSITIVE:游标可以上下移动,一旦它创建后,数据库里的数据再发生修改,对它来说是透明的。
ResultSet.TYPE_SCROLL_SENSITIVE:游标可以上下移动,如果生成后数据库还发生了修改操作,它是能够感知到的。
ResultSet中有两种并发类型。
ResultSet.CONCUR_READ_ONLY:ResultSet是只读的,这是默认类型。
ResultSet.CONCUR_UPDATABLE:我们可以使用的ResultSet的更新方法来更新里面的数据。
java.sql.SQLException:JDBC异常的基类。
java.sql.BatchUpdateException:当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException中。
java.sql.SQLWarning:SQL操作出现的警告信息。
java.sql.DataTruncation:字段值由于某些非正常原因被截断了
DataSource即数据源,它是定义在javax.sql中的一个接口,跟DriverManager相比,它的功能要更强大。我们可以用它来创建数据库连接,当然驱动的实现类会实际去完成这个工作。除了能创建连接外,它还提供了如下的特性:
缓存PreparedStatement以便更快的执行
可以设置连接超时时间
提供日志记录的功能
ResultSet大小的最大阈值设置
通过JNDI的支持,可以为servlet容器提供连接池的功能
execute可以用来执行任意SQL语句,返回一个boolean的值,表明该语句是否返回了一个结果集对象ResultSet。
executeUpdate 用来执行修改,插入,删除操作,执行SELECT会抛出异常
executeQuery只能进行SELECT,从而得到结果集对象,DELETE、UPDATE、INSERT操作都会抛出异常
通常不使用execute,如果你不知道要执行的SQL语句是什么类型的,就可以使用execute。
数据库连接是一种关键的有限的昂贵的资源,对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
JDBC的DriverManager是一个工厂类,我们通过它来创建数据库连接。当JDBC的Driver类被加载进来时,它会自己注册到DriverManager类里面,然后我们会把数据库配置信息传成DriverManager.getConnection()方法,DriverManager会使用注册到它里面的驱动来获取数据库连接,并返回给调用的程序。
RowSet继承自ResultSet,因此它有ResultSet的全部功能,同时它自己添加了些额外的特性。
RowSet一个最大的好处是它可以是离线的,这样使得它更轻量级,同时便于在网络间进行传输。