会话技术
- 一次会话中包含多次请求和响应
- 浏览器第一次给服务器资源发送请求,会话建立,直到一方断开为止
- 在一次会话的范围内的多次请求间,共享数据
Cookie
- 客户端浏览器会话技术,将数据保存到客户端
- 快速入门 :
- 创建Cookies对象,绑定数据
- 发送Cookies对象 : response.addCookies(Cookies cookies);
- 获取Cookies,拿到数据 : Cookies[] request.getCookies();
- 实现原理 : 基于响应头set-cookie和请求头cookie实现
- cookie的细节
- 一次可不可以发送多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
- cookie在浏览器中保存多长时间?
- 正数 : 将Cookie数据写到硬盘的文件中,持久化存储,并指定cookie存活时间,时间到后,cookie文件自动失败
- 负数 : 默认值
- 零 : 删除cookie信息(用于设置存货时间过长,手动删除)
- cookie能不能存储中文?
- tomcat8以后可以存储中文数据
- cookie的获取范围有多大 : 假设在一个tomcat服务器中,部署了多个Web项目中cookie能不能共享?
- 默认情况下cookie不能共享
- setPath(String path) : 设置cookie的获取范围,默认情况下,设置当前的虚拟目录
如果要共享,则可以将path设置为"/" - 不同的tomcat服务器间cookie共享问题:
- setDomain(String path) : 如果设置一级域名相同,那么多个服务器之间cookie可以共享
- setDomain(".baidu.com"),那么tieba,baidu,com和 news.baidu.com中cookie可以共享
- cookie的特点和作用
- cookie存储数据在客户端浏览器
- 浏览器对于单个cookie的大小有限制(4kb) 以及对同一个域名下的总cookie数量也有限制(20个)
- 作用 :
- cookie一般用于存储少量的不太敏感的数据
- 在不登陆的情况下,完成服务器对客户端的身份识别
Session
- 概念 : 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
- 快速入门 :
- 获取HttpSession对象 : HttpSession session = request.getSession();
- 使用HttpSession对象 :
- Object getAttribute(String name)
- void setAttribute(String name,Object value)
- void removeAttribute(String name)
- 原理 : Session的实现是依赖于cookie的;
- 细节 :
- 当客户端关闭后,服务器不关闭,两次获取的session是否为一个
- 默认情况下,不是
- 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
- 客户端不关闭,服务器端关闭后,两次获取的session是否为同一个
- 不是同一个,但是要确保数据不丢失
- session的钝化 : 在服务器正常关闭之前,将session对象系列化到硬盘上
- session的活化 : 在服务器启动后,将session文件转化为内存中的seesion对象即可
- 不是同一个,但是要确保数据不丢失
- session的失效时间
- 服务器关闭
- session对象调用invalidate()
- session默认失效时间是30分钟
- 当客户端关闭后,服务器不关闭,两次获取的session是否为一个
- session的特点
- session用于存储一次会话的多次请求的数据,存在服务器端
- session没有数据大小限制,Cookie有
- session数据安全,cookie相对不安全
JSP
- 概念 : Java Server Page : java服务器端页面 --> 可以理解为 : 一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
- 原理 : 本质就是一个Servlet
- JSP脚本 : JSP定义java代码
- <% 代码 %> : 定义的java代码,在servlet方法中,Servlet方法中可以定义什么,该脚本就可以定义什么
- <%! 代码 %> : 定义的java代码,在jsp转换后的java类的成员变量
- <%= 代码 %> : 定义的java代码,会输出到页面上,输出语句中可以定义什么,就可以定义什么
- JSP的内置对象 :
- 在jsp页面中不需要创建就可以直接使用的对象
- jsp 一共有9个内置对象。
- request , response , out : 字符输出流对象,可以将数据输出到页面上,和response,getwriter()类似
- out.write()和respond.getWriter()的区别 :
- 在tomcat服务器真正给客户端做出响应之前,会先找respond缓冲区数据,再找out缓冲区数据
- response.getWriter()数据输出永远在out.write()之前
- 指令
- 作用 : 用于配置JSP页面,导入资源文件
- 格式 : <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 …%>
- 分类:
- page : 配置JSP页面的
- contentType : 等同于response.setContentType()
- 设置响应体的mime类型以及字符集
- 设置当前 jsp 页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
- import : 导包
- errorPage : 当前页面发生异常后,会自动跳转到指定的错误页面
- isErrorPage : 标识当前页面是否是错误页面
- true : 是, 可以使用内置对象exception
- false : 否, 默认值,不可以使用内置对象exception
- contentType : 等同于response.setContentType()
- include : 页面包含的。导入页面的资源文件
- taglib : 导入资源
- <@% taglib prefix=“c” url="" %>
- prefix : 前缀,自定义的
- page : 配置JSP页面的
- 注释 :
- html注释 : < !-- – > : 只能注释html代码片段
- jsp注释 : < %-- --% > : 可以注释所有
- 内置对象:
- pageContext : 当前页面共享数据
- request : 一次请求访问的多个资源
- session : 一次会话的多个请求间
- application : 所有用户间共享数据
- response : 响应对象
- page : 当前页面(Servlet)的对象 this
- out : 输出对象,数据输出到页面上
- config : Servlet配置对象
- exception : 异常对象
MVC开发模式
- MVC :
-
model : 模型。 JavaBean
- 完成具体的业务操作,如 : 查询数据库,封装对象
-
view : 视图。JSP
- 展示数据
-
control : 控制层 Servlet
- 获取用户的输入
- 调用模型
- 将数据交给视图进行展示
-
优缺点 :
- 优点 :
- 耦合度低,方便维护,可以利用分工协作
- 重用性高
- 使得项目架构变得复杂,对开发人员要求高
- 缺点 :
- 使得项目架构变得复杂,对开发人员要求高
- 优点 :
-
EL表达式
- 概念 : Expression Language 表达式语言
- 作用 : 替换和简化jsp页面中java代码的编写
- 语法 : ${表达式}
- 注意 :
- jsp 默认支持 el 表达式,如果要忽略 el 表达式
- 设置jsp中page指令中 : isELIgnored=“true” 忽略当前jsp页面中所有的 el 表达式
- ${表达式} : 忽略当前这个 el 表达式
- 使用 :
- 运算 :
- 运算符 :
- 算术运算符 : + - * /(div) %(mod)
- 比较运算符 : > < >= <= == !=
- 逻辑运算符 : &&(and) ||(or) !(not)
- 空运算符 : empty
- 功能 : 用于判断字符串,集合,数组对象是否为null并且长度是否为0
- ${empty list} : 判断字符串,集合,数组对象是否为null或者长度是否为0
- ${not empty list} : 判断字符串,集合,数组对象是否不为 null 并且长度 > 0
- 获取值
- el表达式只能从域对象中获取值
- 语法:
- ${域名称.键名} : 从指定的域中获取指定键的值
- 域名称:
- pageScope --> pageContext
- requestScope --> request
- sessionScope --> session
- applicationScope --> application (ServletContext)
- 举例 : 在request域中存储了name=“张三”
- 获取 : ${requestScope.name}
- 域名称:
- ${键名} : 表示依次从最小的域中查找是否有该键对应的值,值找到就停止
- 获取对象 : List集合,Map集合的值
- 对象 : ${域名称.键名.属性名} 本质上会去调用对象的getter方法
- List集合 : ${域名称.键名[索引]}
- Map集合 : ${域名称.键名,key名称} 或者 ${域名称.键名,[“key名称”]}
- ${域名称.键名} : 从指定的域中获取指定键的值
- 隐式对象 :
- el表达式中有11个隐式对象
- pageContext : 获取jsp其它八个内置对象
- ${pageContext.request.contextPath} : 动态获取虚拟目录
JSTL
- 概念 : JavaServer Pages Tag Library JSP标准标签库
- 是由Apache组织提供的开源的免费的jsp标签
- 作用 : 用于简化和替换jsp页面上的java代码
- 使用步骤 :
- 导入jstl相关的jar包
- 引入标签库 : taglib指令 : <%@ taglib %>
- 使用标签
- 常用的JSTL标签
- if : 相当于java代码的if语句
- 属性
- test是必须属性,接收Boolean表达式
- 如果表达式为true.则显示if标签体内容,如果为false,则不显示标签体内容
- 一般情况下,test属性值会结合el表达式一起使用
- 注意 : c:if标签没有else情况,想要else情况,则可以再定义一个if标签
- 属性
- choose : 相当于java代码的switch语句
- 使用choose标签取出数字,相当于switch声明
- 使用when标签做数字判断,相当于case
- otherwise标签做其他情况的声明,相当于
- foreach : 相当于java代码的for语句
- 完成重复的操作
- begin : 开始值
- end : 结束值
- var : 循环变量
- step : 步长
- varStatus : 循环状态对象
- index : 容器中元素的索引,从0开始
- count : 循环次数。从1开始
- 遍历容器
- items : 容器对象
- var : 容器中元素的临时变量
- varstatus : 循环状态对象
- index : 容器中元素的索引,从0开始
- count: 循环次数,从1开始
- 完成重复的操作
- if : 相当于java代码的if语句
三层架构
- 界面层(表示层) : 用户看到的界面,用户可以通过界面上的组件和服务器进行交互
- 业务逻辑层 : 处理业务逻辑的。
- 数据访问层 : 操作数据存储文件
Listener : 监听器
- 概念 : web的三大组件之一(Servlet,Listener,Filter)
- 事件监听机制 :
- 事件 : 一件事件
- 事件源 : 事件发生的地方
- 监听器 : 一个对象
- 注册监听 : 将事件,事件源,监听器绑定在一起。当事件源上的发生某件事件后,执行监听器代码
- ServletContextListener : 监听对象的创建和销毁
- void contextDestroyed(ServletContextEvent sce)
- void contextInitialized(ServletContextEvent sce)
- web.xml配置
<listener>
<listener-class>com.example.Day4.listener.listener1</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>config.xml</param-value>
</context-param>
- 注解配置 : @WebListener 也需要在web.xml中配置< context-param >
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>config.xml</param-value>
</context-param>
< context-param > : 是用于处理xml耦合的问题的
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//读取web.xml中的全局参数
ServletContext servletContext = servletContextEvent.getServletContext();
String context = servletContext.getInitParameter("contextConfiglocation");
ApplicationContext app = new ClassPathXmlApplicationContext(""+context);
//将Spring的应用上下文对象存储到ServletContext域中
servletContext.setAttribute("app",app);
}
Filter : 过滤器
- 概念 :
- web的过滤器 : 当访问服务器的资源时,过滤器是可以将请求拦截下来,完成一些特殊功能
- 过滤器的作用 :
- 一般用于完成通用的操作,如: 登陆验证,统一编码处理,敏感字符过滤…
- 快速入门 :
- 定义一个类,实现接口Filter
- 复写方法
- 配置拦截路径
- web.xml
- 注解 @WebFilter("/*")
- 过滤器的细节 :
- web.xml配置
<filter>
<filter-name>filterdemo1</filter-name>
<filter-class>com.example.Day4.filter.filterdemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>filterdemo1</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispacher>
</filter-mapping>
- 过滤器执行流程
- 执行过滤器
- 执行放行后的资源
- 执行放行代码下边的代码
- 过滤器生命周期方法 init():创建 destory():销毁
- 过滤器配置详解
- 拦截路径配置:
- 具体资源路径 : /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
- 拦截目录 : /user/* 访问/user下的所有资源时,过滤器都会被执行
- 后缀名拦截 : *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
- 拦截所有目录 : /*
- 拦截方式配置 : 资源被访问的方式
- 注解配置 :
- 设置dispatcherTypes属性
- REQUEST : 默认值。浏览器直接请求资源
- FORWARD : 转发访问资源
- INCLUDE : 包含访问资源
- ERROR : 错误跳转页面
- ASYNC : 异步访问资源
- 设置dispatcherTypes属性
- web.xml配置 : < dispatcher >REQUEST</ dispacher >
- 注解配置 :
- 拦截路径配置:
- 过滤器链(配置多个过滤器)
- 执行顺序 : 如果有两个过滤器 : 过滤器1和过滤器2
- 过滤器1–>过滤器2–>资源–>过滤器2–>过滤器1
- 过滤器先后问题 :
- 注解配置 : 按照类名的字符串比较规则比较,值小的先执行
- web.xml配置 : 谁定义在上面谁先执行
- 执行顺序 : 如果有两个过滤器 : 过滤器1和过滤器2
代理模式
- 概念 :
- 真实对象 : 被代理的对象
- 代理对象 :
- 代理模式 : 代理对象代理真实对象,达到增强真实对象功能的目的
- 实现方式 :
- 静态代理 : 有一个类文件描述代理模式
- 动态代理 : 在内存中形成代理类
- 实现步骤 :
- 代理对象和真实对象实现相同的接口
- 代理对象 = Peoxy.newInstance();
- 使用代理对象调用方法
- 增强方法 :
- 增强参数列表
- 增强返回值类型
- 增强方法体执行逻辑
- 实现步骤 :
package com.example.Day4.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
sale sale = new sale();
//2.动态代理增强sale对象
/**
* 三个参数
* 1.类加载器
* 2.接口数组
* 3.处理器 : new InvocationHandler()
*/
SaleComputer proxy_sale = (SaleComputer) Proxy.newProxyInstance(sale.getClass().getClassLoader(), sale.getClass().getInterfaces(), new InvocationHandler() {
/*
代理逻辑编写的方法,代理对象调用的所有方法都会触发该方法执行
参数:
1. proxy:代理对象
2. method : 代理对象调用的方法,被封装为的对象
3. args : 代理对象调用的方时,传递的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("该方法执行了.......");
//1.增强参数
//判断是否是sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money = (double) args[0];
money = money*0.85;
System.out.println(money);
//使用真实对象调用该方法
String obj = (String) method.invoke(sale, money);
//2.增强返回值
return obj+"_鼠标垫";
}else{
//使用真实对象调用该方法
Object obj = method.invoke(sale, args);
return obj;
}
}
});
String computer = proxy_sale.sale(8000);
System.out.println(computer);
}
}