Filter:过滤器的作用
Filter(过滤器)的功能:
filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).
一个Filter包括:
1)、在servlet被调用之前截获;
2)、在servlet被调用之前检查servlet request;
3)、根据需要修改request头和request数据;
4)、根据需要修改response头和response数据;
5)、在servlet被调用之后截获.
Filter 的基本工作原理
- 1、Filter 程序是一个实现了特殊接口的 Java 类,与 Servlet 类似,也是由 Servlet 容器进行调用和执行的。
- 2、当在 web.xml 注册了一个 Filter 来对某个 Servlet 程序进行拦截处理时,它可以决定是否将请求继续传递给 Servlet 程序,以及对请求和响应消息是否进行修改。
- 3、当 Servlet 容器开始调用某个 Servlet 程序时,如果发现已经注册了一个 Filter 程序来对该 Servlet 进行拦截,那么容器不再直接调用 Servlet 的 service 方法,而是调用 Filter 的 doFilter 方法,再由 doFilter 方法决定是否去激活 service 方法。
- 4、但在 Filter.doFilter 方法中不能直接调用 Servlet 的 service 方法,而是调用 FilterChain.doFilter 方法来激活目标 Servlet 的 service 方法,FilterChain 对象时通过 Filter.doFilter 方法的参数传递进来的。
- 5、只要在 Filter.doFilter 方法中调用 FilterChain.doFilter 方法的语句前后增加某些程序代码,这样就可以在 Servlet 进行响应前后实现某些特殊功能。
- 6、如果在 Filter.doFilter 方法中没有调用 FilterChain.doFilter 方法,则目标 Servlet 的 service 方法不会被执行,这样通过 Filter 就可以阻止某些非法的访问请求。
Filter生命周期:
Filter的创建和销毁是由web服务器负责。Web应用程序启动的时候,web服务器创建Filter的实例对象。
并调用其init方法进行初始化(filter对象只会创建一次,init方法也只会执行一次)。
每次filter进行拦截的时候,都会执行doFilter的方法。
当服务器关闭的时候,应用从服务器中移除的时候,服务器会销毁Filter对象。
源码;
Cookie[] cookies = httpServletRequest.getCookies();
boolean flag = false;
//查看浏览器中是否有cookie
if(cookies != null && cookies.length > 0){
//浏览器中有cookie 进行循环遍历 查找一周内登陆的cookie
for(Cookie cookie : cookies){
if("loginInfo".equals(cookie.getName())){
//对cookie进行base64解码 校验cookie防止被串改
Decoder decoder = Base64.getDecoder();
byte[] decode = decoder.decode(cookie.getValue());
String string = new String(decode);
if(string.equals("tom&123456")){
//找到并设置标志位
flag = true;
}
}
}
//根据标志位进行顾虑请求 特别理解标志位的使用
if(flag){
chain.doFilter(request, response);
}else{
httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login.jsp");
}
}
//浏览器中没有一个cookie
else{
httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login.jsp");
}
}
Listener(监听器):
Listener的概述:
监听你的web应用,监听许多信息的初始化,销毁,增加,修改,删除值等
Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理。
1.Listener是Servlet的监听器
2.可以监听客户端的请求、服务端的操作等。
3.通过监听器,可以自动激发一些操作,如监听在线用户数量,当增加一个HttpSession时,给在线人数加1。
4.编写监听器需要实现相应的接口
5.编写完成后在web.xml文件中配置一下,就可以起作用了
6.可以在不修改现有系统基础上,增加web应用程序生命周期事件的跟踪
servlet 规范中为每种事件监听器都定义了相应的接口,在编写事件监听器程序时只需实现这些接口就可以了。一些Servlet事件监听器需要在web应用程序的部署 文件描述符文件(web.xml)中进行注册(注册之后才能发布),一个web.xml可以注册多个servlet事件监听器。web服务器按照它们在web.xml中注册顺序来加载和注册这些servlet事件监听器。servlet事件监听器的注册和调用过程都是由web容器自动完成的,当发生被监听对象被创建,修改,销毁等事件时,web容器将调用与之相关的servlet事件监听器对象的相应方法(所监听到的对象如果在创建、修改、销毁事件触发的时候就会调用这些监听器这就相当于面向事件编程的概念),用户在这些方法中编写的事件处理代码(相当于JS中的事件响应)即被执行。由于在一个web应用程序中只会为每个事件监听器类创建一个实例对象,有可能出现多个线程同时调用一个事件监听对象的情况,所以要注意多线程安全问题。
监听器的类型:
按监听的对象划分:servlet2.4规范定义的事件有三种:
1.用于监听应用程序环境对象(ServletContext)的事件监听器
2.用于监听用户会话对象(HttpSession)的事件监听器
3.用于监听请求消息对象(ServletRequest)的事件监听器
按监听的事件类项划分
1.用于监听域对象自身的创建和销毁的事件监听器
2.用于监听域对象中的属性的增加和删除的事件监听器
3.用于监听绑定到HttpSession域中的某个对象的状态的事件监听器
在一个web应用程序的整个运行周期内,web容器会创建和销毁三个重要的对象,ServletContext,HttpSession,ServletRequest。
分类及介绍:
1. ServletContextListener:用于监听WEB 应用启动和销毁的事件,监听器类需要实现javax.servlet.ServletContextListener 接口。
2. ServletContextAttributeListener:用于监听WEB应用属性改变的事件,包括:增加属性、删除属性、修改属性,监听器类需要实现javax.servlet.ServletContextAttributeListener接口。
3. HttpSessionListener:用于监听Session对象的创建和销毁,监听器类需要实现javax.servlet.http.HttpSessionListener接口或者javax.servlet.http.HttpSessionActivationListener接口,或者两个都实现。
4. HttpSessionActivationListener:用于监听Session对象的钝化/活化事件,监听器类需要实现javax.servlet.http.HttpSessionListener接口或者javax.servlet.http.HttpSessionActivationListener接口,或者两个都实现。
5. HttpSessionAttributeListener:用于监听Session对象属性的改变事件,监听器类需要实现javax.servlet.http.HttpSessionAttributeListener接口。
源码:
public WebContextListener() {
System.out.println("ServletcontextListener的构造器");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("容器关闭的时候调用");
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("容器启动的时候调用");
}
}
Session:
引入session:
session会话机制。
Session一般是指浏览器这个页面打开到关闭的这段时间。所谓的使用session机制其实就是不把用户信息存到浏览器(客户端)而是全部存到服务器上,我们只存一个被称为sessionid的值作为cookie存在浏览器端。
原理:
Session原理是服务端端每一个session维护一份会话信息数据,客户端和服务端依靠一个全局唯一标识sesssion_id来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session。
session对象是在第一次调用request.getSession()或者request.getSession(true)时创建的。
服务器在创建session之后,会为每一个session分配一个唯一的id作为标示服务器会为每一个用户的浏览器创建一个独享的session对象。
向session中保存数据
session.setAttribute("name", "adlkdksl");
通过session获取保存的数据,当获取的属性不存在时,返回的结果为null
String name = (String) session.getAttribute("name");
在同一个会话中 ,session的id都是相同的
关于SessionID :
session的id是从哪里来的,sessionID是如何使用的:当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象,当浏览器下次(session继续有效时)请求别的资源的时候,浏览器会将sessionID(实质是cookie)放置到请求头中,服务器接收到请求后就得到该请求的sessionID,服务器找到该id的session返还给请求者(Servlet)使用。一个会话只能有一个session对象,对session来说是只认id不认人。
关于session_id的时效性;
一般来说我们用session保持持久连接,也就是用户登录认证通过后,保持对这个用户的识别。 但是我们这个登录必须设置一个时效,也就是说登录了一段时间后我们要求用户重新登录。
其实也就是设置cookie(session_ID)的有效时间,当超过时了这个session_Id就无效了,我们就要再次登录,再次输入认证信息,然后服务器接收这些信息再次生成一个新的session,并把用户认证的信息存入这个session。
一般session也是有有效期的,可能是用户主要销毁,比如登出操作,这个session就销毁了
可以通过cookie,设置JSESSIONID的生命周期
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(6000);
response.addCookie(c);
session.setMaxInactiveInterval()设置session的失效时间
设置session以后,每次浏览器启动时都会查找JSESSIONID来找以往的session
如果找不到或者为空,则创建新的session。
调用getSession()方法后,就会创建session。
request.getSession(true);标示如果没有对应的JSESSIONID对象,
就会创建一个新的JSESSIONID为id的session对象,通常用来创建session对象
request.getSession(false);如果没有对应的JSESSIONID对象
则返回null;通常用来获取session对象
安全:
Session机制中,数据是存储在服务器上面,所以你不能伪造,你要获得这些数据就必须使用服务提供的sesssion_id,Cookie是保存在客户端的,安全性很难得到保证。
再者Session_id和session:
Session的话其实主要看session_id,大部分的会话机制是利用session_id(也是cookie),如果cookie过期了也就是session_id过期了,那么显然服务器中的session也会结束生命周期(被销毁)。(如果浏览器没有删除cookie,你发送了一个过期的cookie,服务器需要判断然后就会拒绝你的请求)
Session过期
session自动失效:一般服务器也会设置Session的过期时间,一旦session过期了,就算客户端的cookie(session_id)没有过期,session照样会结束自己的生命周期。