Filter
总体来说Filter有三个阶段,分别是初始化,拦截过滤,和销毁;主要来说
就是拦截和过滤的阶段
过滤器的拦截和过滤
配置Filter的拦截路径有两种方式,一种是注解,一种是xml方式
https://www.yarong.cn:8080/search?w=ajax
1.https
是协议;
2.www.yarong.cn是域名;
3.8080是端口号;
4./search是路径;
5.?w=ajax是URL地址带的参数
1.路径不同,同源
2.协议不同,不同源
3.域名不同,不同源
4.端口不同,不同源
跨源资源共享,它允许浏览器向声明了
CORS 的跨域服务器,发出
XMLHttpReuest 请求,从而克服 Ajax 只能同源使用的限制
1.初始化阶段:当服务器启动的时候,服务器就会读取配置文件,扫描注
解,然后创建
filter
2.
拦截和过滤阶段:只要请求资源的路径和拦截的路径相同,那么过滤器就
会对请求进行过滤,这个阶段在服务器运行过程中会一直循环
3.销毁阶段:当服务器(tomcat)关闭的时候,服务器创建的Filter也会
随之销毁。
过滤器的生命周期
Filter的生命周期可以简述为三个阶段即:初始化,拦截过滤,销毁,三
个阶段分别对应三个方法:
init方法会在创建Filter的时候调用,doFilter方
法会在请求和拦截的时候调用,
destroy方法会在Filter销毁的时候调用。
1.注解方式:
如果使用注解来配置,那么我们就需要
@WebFilter来进行配置
eg:@WebFilter(value={"/*"},filterName="myFilter")
如果我们仅仅需要配置一个拦截路径,那么我们可以以直接简写
@WebLister("拦截路径"),如@WebFilter("/*")就是拦截所有的请求。
2.xml方式:
myFilter
com.clucky.filter.MyFilter
myFilter
/*
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class LifeCycleFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws
ServletException {
//这个方法就是初始化方法,在Filter创建时调用
System.out.println("调用了init()方法");
}
@
Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
FilterConfig和FilterChain
1.FilterConfig
通常在init方法中调用FilterConfig来读取配置的数据库信息然后输出
2.FilterChain
FilterChain
主要是用来对请求的数据过滤之后进行放行
eg:
//这个方法就是过滤和拦截的方法,当请求和拦截匹配时调用
System.out.println("调用了doFilter()方法");
//对过滤之后的数据放行
filterChain.doFilter(servletRequest,servletResponse);
} @
Override
public void destroy() {
//这个方法就是销毁方法,在Filter销毁前调用
System.out.println("调用了destroy()方法");
}
}
//eg:
@Override
public void init(FilterConfig filterConfig) throws
ServletException {
System.out.println("-----------获取全部
key:value------------");
//得到所有配置参数的名字
Enumeration
filterConfig.getInitParameterNames();
while (names.hasMoreElements()) {
//得到每一个名字
String name = names.nextElement();
System.out.println(name+" =
"
+filterConfig.getInitParameter(name));
}
S
ystem
.out.println("-----------end.....-------
-----"
);
}
Cooki——Session-token
我们都知道 HTTP 协议是无状态的,所谓的无状态就是客户端每次想要与
服务端通信,都必须重新与服务端链接,意味着请求一次客户端和服务端
就连接一次,下一次请求与上一次请求是没有关系的。解决客户的标识问
题
三者区别:
cookie和session的区别
token认证流程
filterChain.doFilter(servletRequest,servletResponse);
1. cookie
是存储再浏览器端的一小段文本。
2. seesion是存储在服务器端的一组数据
3. token通常代表一小段字符串,可以存储到cookie里,随请求一起发过去,
也可以存在服务器中
session 比 cookie 更加安全,因为它是存在服务端的,cookie 是存在客
户端的。
cookie 只支持存储字符串数据,session 可以存储任意数据。
cookie 的有效期可以设置较长时间,session 有效期都比较短。
session 存储空间很大,cookie 有限制。
客户端发起登录请求,比如用户输入用户名和密码后登录。
服务端校验用户名和密码后,将用户
id 和一些其它信息进行加密,生成
token。
服务端将
token 响应给客户端。
客户端收到响应后将
token 存储下来。
下一次发送请求后需要将
token 携带上,比如放在请求头中或者其它地方。
服务端
token 后校验,校验通过则正常返回数据。
cookie的认证流程:
Cookie描述:
session描述:
Cookie是运行在客户端,
1.客户端发送请求到服务端(比如登录请求)。
2.服务端收到请求后生成一个 session 会话。
3.服务端响应客户端,并在响应头中设置 Set-Cookie。Set-Cookie 里面包
含了
sessionId,它的格式如下:Set-Cookie: value[;
expires=date][; domain=domain][; path=path][; secure]
。其中
sessionId 就是用来标识客户端的,类似于去饭店里面,服务员给你一个号
牌,后续上菜通过这个号牌来判断上菜到哪里。
4。客户端收到该请求后,如果服务器给了 Set-Cookie,那么下次浏览器就会
在请求头中自动携带
cookie。
5.客户端发送其它请求,自动携带了 cookie,cookie 中携带有用户信息
等。
6.服务端接收到请求,验证 cookie 信息,比如通过 sessionId 来判断是
否存在会话,存在则正常响应。
cookie 是保存在客户端或者说浏览器中的一小块数据,大小限制大致在 4KB
左右,在以前很多开发人员通常用 cookie 来存储各种数据,后来随着更多浏
览器存储方案的出现,
cookie 存储数据这种方式逐渐被取代,主要原因有如
下:
cookie 有存储大小限制,4KB 左右。
浏览器每次请求会携带
cookie 在请求头中。
字符编码为
Unicode,不支持直接存储中文。
数据可以被轻易查看。
session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里
面有没有包含
sessionId 标识,如果包含了 sessionId,则代表服务端已
经和客户端创建过
session,然后就通过这个 sessionId 去查找真正的
session,如果没找到,则为客户端创建一个新的 session,并生成一个新的
sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户
端,通常是存储在
cookie 中。如果在请求中找到了真正的 session,验证
通过,正常处理该请求。
Session是运行在服务器端。
cookie只是一个储存在用户本地终端上的数据文件
IO流
解释:
流的划分:
注意: 对文件的读使用Input输入流 对文件的写操作使用Output输出流
流的分类:
字符流和字节流的转换:
字节流和字符流的区别:
读取为输入流:inputStreamReader
写入为输出流:outPutStreamWriter
按照流向分可以分为输入流和输出流;
按照操作单元划分可以分为,字节流和字符流
按照流的角色划分可以分为,节点流和处理流
I/O: I表示Input输入
操作O表示Output输出
主要作用就是对文件读写
1.输入流:Reader:就是把要读取的文件中的字节序列转化为字符存储在内存
中
2.
输出流:Witer:就是把要写人文件的字符序列,转化为字节序列然后存在文
件中
字节流转换为字符流:需要使用
inputStreamReader
字符流转换为字节流:需要用outputStreamWriter
序列化
序列化方式:
序列化流
对象输出流
:它的writeObject(Object obj)方法可以对指定obj对象参数进
行序列化,再把得到的字节序列写到一个目标输出流中。
对象输入流
:它的readObject()方法,从输入流中读取到字节序列,反序
列化成为一个对象,最后将其返回。
json数据格式的作用:
基础类型JSON序列化
对象序列化:
将Java对象转换为JSON字符串最基本的方法就是使用ObjectMapper类的
writeValueAsString方法。这个方法接收一个Java对象作为参数,返回一个
JSON字符串。
1. 字节流、<字节流是以节点为单位,可以操作任何数据,但是不能对
Unicode进行处理>
3.
字符流<字符流是以字符为单位,只能操作纯字符数据,比较方便可以对
Unicode进行处理>
凡是InputStream或OutputStream结尾的都是字节流 所有字节流的
根父类InputStream/OutputSteam 抽象类
凡是
Reader或Writer结尾的都是字符流
Reader/Writer 抽象类
所有字符流的根父类
3. 节点流、处理流
节点流:凡是直接关联数据源的就是节点流
(根据构造器来判断是否关联数
据源
)
处理流:如果构造器不是直接关联数据源(字节流的根父类或字符流的根父
类:抽象类
) 就可以确定是处理流.
1.
前后端交互使用的数据格式
2.他是以键值对存储的
集合序列化
除了序列化单个Java对象,Jackson库还支持序列化Java集合,包括List、
Set和Map等。可以使用ObjectMapper类的
枚举类型的序列化
在Java中,枚举类型是一种常见的数据类型,它通常用于表示一组有限的
值。使用
Jackson库将枚举类型序列化为JSON字符串也是常见的操作。下面
是一个简单的枚举类型的定义
要将枚举类型序列化为
JSON字符串,我们只需要在类上添加@JsonFormat
注解,并指定序列化的格式。例如,以下代码将会使用大写字母序列化枚
举类型:
ObjectMapper mapper = new ObjectMapper();
User user = new User("Tom", 20);
String json = mapper.writeValueAsString(user);
结果:{"name":"Tom","age":20}
writeValueAsString方法将Java集合序列化为JSON字符串。
ObjectMapper mapper = new ObjectMapper();
List
users.add(new User("Tom", 20));
users.add(new User("Jerry", 22));
String json = mapper.writeValueAsString(users);
结果:[{"name":"Tom","age":20},
{
"name":"Jerry","age":22}]
public class User {
private String name;
private int age;
private Gender gender;
// getters and setters
} O
bjectMapper mapper
= new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
User user = new User();
user.setName("Tom");
在上面的代码中,我们先定义了一个User类,其中包含一个枚举类型的字
段
gender。然后,我们使用ObjectMapper类将User对象序列化为JSON字
符串,并将结果打印出来。可以看到,枚举类型的值已经被序列化为字符
串类型了。
Json的转换工具有什么:
生命周期
线程的生命周期
user.setAge(20);
user.setGender(Gender.MALE);
String json = mapper.writeValueAsString(user);
System.out.println(json);
输出结果如下:
{ "
name"
: "Tom",
"age" : 20,
"gender" : "MALE"
} 如
何转换为
json格式
1.JSON.stringify(对象);将指定对象转换为json格式字符串
2.JSON.parse(字符串);将指定json格式字符串解析成对象
Jackson工具
1.常用类有ObjectMapper(是jackson工具包的核心类,他提供一些方
法来实现
JSON字符串和对象之间的转换)
2.TyeReference(对集合的反序列化,使用TypeRefence可以明确的
指定反序列化的对象类型)
VUE的生命周期
servet生命周期
1.新建状态
2.就绪状态
3.运行状态
4.阻塞状态
5.死亡状态
1.beforeCreat() 创建前 在new一个vue实例后,只有一些默认的生命周期
钩子和默认事件,其他的东西都还没创建。在此生命周期执行的时候,
data和
methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和
methods中的方法
2.created()被创建 data 和 methods都已经被初始化好了,可以调用了
3.beforeMount() 挂载前 在内存中已经编译好了模板了,但是还没有挂载到
页面中,此时,页面还是旧的
4.mounted()已挂载 Vue实例已经初始化完成了。此时组件脱离了创建阶
段,进入到了运行阶段。 如果我们想要通过插件操作页面上的
DOM节点,最早可
以在和这个阶段中进行
5.beforeupdate()更新前 页面中的显示的数据还是旧的,data中的数据是
更新后的, 页面还没有和最新的数据保持同步
6.updated()更新 页面显示的数据和data中的数据已经保持同步了,都是最
新的
7.beforeDestroy() 销毁前 Vue实例从运行阶段进入到了销毁阶段,这个时
候上所有的
data 和 methods , 指令, 过滤器 ……都是处于可用状态。还
没有真正被销毁
8.destroyed()被销毁 这个时候上所有的 data 和 methods , 指令,
过滤器
……都是处于不可用状态。组件已经被销毁了。
创建
Servlet对象后---------->初始化(调用 init () 方法)--------
->
处理/响应客户端的请求(调用 service() 方法)--------->销毁(调用
destroy() 方法,最后由 JVM 的垃圾回收器进行垃圾回收)