1 过滤器监听器概念
1 过滤器
例如:水龙头上的滤网、净水器
所有经过该滤网的水资源都会被过滤,过滤的物质有滤网的特点来决定的
可以拦截指定的请求和响应,进行一系列的业务处理
问题:业务场景有哪些
编码过滤、登录过滤、加密过滤等等
问题:过滤规则有哪些
servlet的生命周期:初始化(一次) service(多次) 销毁(一次)
过滤器的生命周期:初始化(一次) doFilter(多次) 销毁(一次)
当有多个过滤器时,就会形成过滤器链,此时需要考虑过滤器的执行顺序,按照在xml中的先后顺序执行
2 监听器
例如:监控摄像头、声控灯
统计在线用户信息
1、在线---用户当前正在使用客户端等行为就成为在线状态,就是当session对象被创建的时候就相当于在线,session销毁时相当于下线
监听session的创建和销毁动作
2、用户信息:IP地址、登录时间等等
思路:
当session创建时,获取相关的信息,然后将获取到的信息存储到一个集合中,再将集合中的信息遍历出来
当session销毁时,要将当前的session对象的用户的信息从集合中移除掉,模拟用户下线的动作
为了能够在整个项目中保证数据的一致性,将集合存储到全局作用域(application)中,只需要在session的创建和销毁中拿来使用即可
3 对象和对象变量的区别
问题:下面哪个定义的是对象?
(1)Date date;
(2)Date date1=new Date();
答案:(2)定义的才是一个对象,而(1)定义的是一个对象变量,一个对象变量不是对象。为什么不是对象?因为没有对象让它引用。
如何date使用Date类的方法,会报错的,为什么?因为没有引用任何对象,你可以先赋值为null。new Date()构造一个对象,并把创建的对象给date1引用。
Date()是一个构造器,构造器是干嘛用的?构造器是实例化对象的状态的。
一个对象应该至少有3个特征:
行为,状态、标识等
2过滤器
2.1登录页面jsp代码
<div class="login layui-anim layui-anim-up">
<div class="message">x-admin2.0-管理登录</div>
<div id="darkbannerwrap"></div>
<form method="post" class="layui-form" action="loginServlet">
<input name="username" placeholder="用户名" type="text" lay-verify="required" class="layui-input" >
<hr class="hr15">
<input name="password" lay-verify="required" placeholder="密码" type="password" class="layui-input">
<hr class="hr15">
<input value="登录" lay-submit lay-filter="login" style="width:100%;" type="submit">
<hr class="hr20" >
</form>
</div>
2.2 登录流程过滤器
/**
* 模拟访问权限控制
* 如果用户没有登陆,那就跳转到登陆页面,如果登录了就直接打开该页面
*/
public class LoginFilter implements Filter{
@Override
public void destroy() {
System.out.println("LoginFilter 销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("LoginFilter doFilter");
//获取HttpServletRequest对象
HttpServletRequest httpRequest = (HttpServletRequest)request;
HttpServletResponse httpResponse = (HttpServletResponse)response;
//获取session中存储的用户名,如果存在就放过,不存在就跳转到login.jsp
HttpSession session = httpRequest.getSession();
Object obj = session.getAttribute("user");
if(null == obj) {
//如果为空就代表用户未登录,跳转到登陆页面
httpResponse.sendRedirect("../login.jsp");
return;
}
//如果用户不为空就放过
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("LoginFilter 初始化");
}
}
2.3字符编码过滤器
public class CharacterFilter implements Filter{
@Override
public void destroy() {
System.out.println("CharacterFilter 销毁");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("CharacterFilter doFilter");
//设置字符编码
request.setCharacterEncoding("utf-8");
//拦截请求,业务处理之后该请求怎么办
//请求放过
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterFilter 初始化");
}
}
3 监听器
public class SessionListenerCls implements HttpSessionListener{
List<SessionBean> sessionBeanList = null;
@Override
public void sessionCreated(HttpSessionEvent sessionEvent) {
//先从全局作用域中获取集合信息,判断该集合是否存在---如果是第一访问项目,此时集合还不存在
ServletContext context = sessionEvent.getSession().getServletContext();
Object obj = context.getAttribute("sessionBeanList");
if(null == obj) {
sessionBeanList = new ArrayList<SessionBean>();
}else {
sessionBeanList = (List<SessionBean>)obj;
}
HttpSession session = sessionEvent.getSession();
String sessionId = session.getId();
//在存储信息时,要保证在线用户是不重复的,在存储之前先判断该用户是否已经存在
for(SessionBean bean : sessionBeanList) {
//如果集合中已存在,说明该用户已经是存在于在线用户的列表中了
if(sessionId.equals(bean.getSessionId())) {
return;
}
}
long createTime = session.getCreationTime();
SessionBean sessionBean = new SessionBean();
sessionBean.setCreateTime(createTime);
sessionBean.setSessionId(sessionId);
sessionBeanList.add(sessionBean);
//更新全局作用域中的集合数据
context.setAttribute("sessionBeanList", sessionBeanList);
}
/**
* session销毁时,当前要销毁的sessionId从集合中对应的对象给移除掉,模拟用户下线的动作
*/
@Override
public void sessionDestroyed(HttpSessionEvent sessionEvent) {
HttpSession session = sessionEvent.getSession();
//先获取全局作用域中的集合数据
ServletContext context = session.getServletContext();
List<SessionBean> sessionBeanList = (List<SessionBean>) context.getAttribute("sessionBeanList");
//获取当前要销毁的sessionId
String destorySessionId = session.getId();
//遍历集合,将对应destorySessionId的对象从集合中移除
for(SessionBean bean : sessionBeanList) {
if(destorySessionId.equals(bean.getSessionId())) {
//将对象从集合中移除
sessionBeanList.remove(bean);
}
}
//更新全局作用域中的集合数据
context.setAttribute("sessionBeanList", sessionBeanList);
}
}
4 在xml文件中配置过滤器监听器
监听器:
<listener>
<listener-class>cn.yunhe.listener.SessionListenerCls</listener-class>
</listener>
过滤器:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.yunhe.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- /pages/* 过滤pages文件夹下的所有请求 -->
<url-pattern>/pages/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>cn.yunhe.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<!-- 过滤规则
/* 拦截所有的请求
-->
<url-pattern>/*</url-pattern>
</filter-mapping>
servelet:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.yunhe.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet.do</url-pattern>
</servlet-mapping>