学习主题:过滤器filter,listener 监听器
学习目标:
1 掌握 filter的作用
2 掌握filter的编写
3 掌握监听器的作用
4 掌握监听器的编写
1.过滤器的介绍
根据视频中的讲解,完成以下内容
(1)视频中的引入过滤器提到的项目中存在的问题是什么问题?
目前我们访问Servlet,是可以直接进行访问的,没有进行任何防护。可能会造成服务器资源的浪费,以及安全性不高。我们希望真的在请求被Servlet处理之前,进行一次请求的校验,符合要求再调用对应的Servlet进行请求处理
(2)根据视频讲解说说你对过滤器的理解,以及你觉得过滤器的作用是什么?
目前我们访问Servlet,是可以直接进行访问的,没有进行任何防护。可能会造成服务器资源的浪费,以及安全性不高。所以需要引入过滤器。
2.过滤器的创建和配置
(1)视频中在代码注释中描述的问题是什么?
过滤器之间会出现多重拦截,如果是按照拦截拦截范围的大小在web.xml中自大而小进行的配置,则会先执行大范围的拦截器,再执行小范围的拦截器。
(2)创建过滤器要实现的接口是?
Filter
(3)创建的过滤器类中需要实现的三个方法是?
doFilter方法 , init和destory方法
(4)在web.xml中配置过滤器的代码是?
<!-- 过滤器配置 -->
<filter>
<filter-name>my</filter-name>
<filter-class>com.bjsxt.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>my</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.过滤器之doFilter和init和destory方法
(1)doFilter方法的作用是?参数是及作用是?
服务器在接收到浏览器发过来的请求后,先解析请求信息,创建对象request和response然后根据请求URL地址判断如果符合过滤器的过滤范围,则会调用过滤器中的doFilter来进行请求拦截,并将request和response对象作为实参传递给doFilter方法。我们可以在doFilter方法中声明过滤器拦截代码。
(2)init方法的执行时机是?
服务器启动时调用
(3)destory方法的执行时机是?
服务器关闭时调用
4.过滤器之拦截范围的配置
(1)过滤器的拦截范围的配置是?及拦截的范围是什么?
拦截所有:/*
拦截部分Servlet的请求:*.do
拦截指定Servlet的请求:和要拦截的指定的Servlet的url-pattern配置完全一致即可,例如:/my
注意:过滤器之间会出现多重拦截,如果是按照拦截拦截范围的大小在web.xml中自大而小进行的配置则会先执行大范围的拦截器,再执行小范围的拦截器。
5.过滤器案例之统一请求编码格式
(1)根据视频讲解使用过滤器完成编码格式的统一设置。
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置请求编码格式
request.setCharacterEncoding("utf-8");
//设置响应编码格式
response.setContentType("text/html;charset=utf-8");
//强转request对象
HttpServletRequest req=((HttpServletRequest) request);
//强转response对象
HttpServletResponse resp=((HttpServletResponse)response);
//获取session对象
HttpSession session = req.getSession();
Object obj=session.getAttribute("user");
if(obj !=null){
//放行
chain.doFilter(request, response);
}else{
//重定向
resp.sendRedirect("/js/login.jsp");
}
6.过滤器之session管理放行登录页面和登录请求
(1)视频中的session管理的基本思路是什么?
在过滤器中获取session对象,然后查看session中的数据是否还在
如果数据没了,则因为session失效则重定向到登录页面。如果数据在
session没有失效,则放行
(2)视频中在过滤器中实现的session管理存在的问题是?
在过滤器中使用session校验后发现登录页面的访问成了死循环,因为登录页面的请求也就是login.jsp的请求也会被过滤器拦截,而此时session中没有相关数据的造成又重定向到登录页面…
解决1:
对login.jsp和登录请求进行放行
7.过滤器之session管理静态资源放行和登录页面跳转
(1)视频中session管理的代码仍然存在的问题是?
过滤器会拦截所有的请求,包括静态资源(css文件\js文件\image图片)请求也会拦截。造成页面中的样式和动态效果等出不来
8.过滤器之session管理ajax请求优化
(1)根据视频讲解在session管理代码中完成ajax请求的优化处理。
function del(uid){
if(confirm("您确定要删除吗?")){
$.get("data",{method:"deleteInfo",uid:uid},function(data){
if("true"==data){
if(eval(data)){
alert("用户删除成功");
window.location.href = "data?method=selAllUser";
}
}else{
window.location.href=location.href;
}
});
}
}
9.过滤器之权限管理功能需求分析和数据库设计
(1)权限管理的需求是什么?。
不同的用户在对同一功能使用时,有的用户可以直接使用,有的用户会被提示权限不足。
(2)视频中讲解的思路是什么?
1、在数据库中创建一个URL权限表,该表存储了该系统需要被管理的URL。
2、在数据库中创建用户权限中间表,用来进行权限分配
3、在数据库中将权限给用户分配好
4、在用户登录成功后查询该用户具备的URL权限,存储到该用户的session中
5、在过滤器中对当前发起请求的用户的请求地址进行校验,校验该用户是否具备该请求地址的权限,如果具备则放行执行,如果不具备则提示权限不足。
10.过滤器之权限管理功能数据实现和登录查询权限实现
if("/project2/login.jsp".equals(uri) || ("/project2/data".equals(uri)&& "userLogin".equals(method)) || uri.startsWith("/project2/css/") || uri.startsWith("/project2/js/")|| uri.startsWith("/project2/images/")){
//放行
chain.doFilter(request, response);
}else{
//session管理(session统一校验)
//获取Session对象
HttpSession session = req.getSession();
Object obj=session.getAttribute("user");
//判断
if(obj!=null){
//获取权限信息
List<Url> lu=(List<Url>) session.getAttribute("lu");
//权限校验
for(Url url:lu){
if(url.getLocation().equals(method) || url.getLocation().equals(uri)){
//放行
chain.doFilter(request, response);
return;
}
}
//响应
resp.getWriter().write("power");
return;
}else{
//重定向到登录页面
resp.sendRedirect("/project2/login.jsp");
}
}
11.监听器的引入和介绍
(1)视频中统计当前在线人数的思路是什么
统计当前系统的session个数,每个session都对应一个在线的用户。在session被创建的时候计数器+1,session被销毁的时候计数器-1,计数器数据存储在servletContext对象中。
(2)视频中的监听器的作用是什么?
用于监听ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中属性发生修改的事件,并进行一些处理。
12.监听器的引入和介绍
(1)视频中统计当前在线人数的思路是什么
增加监听器
(2)视频中的监听器的作用是什么?
监听request、session、application三个域对象的创建,销毁和数据的变更
(3)完成删除功能的Servlet的实现
//删除信息
public void delUser(HttpServletRequest req, HttpServletResponse resp) throws IOException{
//获取请求信息
int uid = Integer.parseInt(req.getParameter("uid"));
//处理请求信息
UserService us = new UserServiceImpl();
int num = us.delUserInfoService(uid);
//响应处理结果
//请求转发
if(num>0){
resp.getWriter().write("true");
}else{
resp.getWriter().write("false");
}
}
<script type="text/javascript">
//判断用户是否请求ajax请求进行删除
function del(uid){
if(confirm("您确定要删除吗?")){
//发起ajax请求进行用户删除
$.get("data",{method:"delUser",uid:uid},function(data){
if(eval(data)){
alert("用户删除成功");
window.location.href="data?method=selUserInfo";
}
});
}
}
</script>
13.监听器的使用之监听request对象
(1)监听request对象的两个接口什么?
ServletRequestListener
ServletRequestAttributeListener
(2)监听request对象的两个接口的方法是?作用分别是?
监听request的创建和销毁:ServletRequestListener
requestInitialized(ServletRequestEvent sre)
requestDestroyed(ServletRequestEvent sre)
形参:
ServletRequestEvent可以获取当前监听到的request对象,对 request对象的中的资源进行操作。
监听request作用域数据的变ServletRequestAttributeListener
attributeAdded(ServletRequestAttributeEvent srae)
attributeRemoved(ServletRequestAttributeEvent srae)
attributeReplaced(ServletRequestAttributeEvent srae)
形参:
ServletRequestAttributeEvent可以获取当前被监听到的 request中的数据。
geName()返回监听到的数据的键和getValue()返回监听的到的数据的值。
(3)在web.xml配置监听器的标签是?给出一个配置示例
<!-- 监听器的配置 -->
<listener>
<listener-class>com.bjsxt.listener.MyListener</listener-class>
</listener>
14.监听器之监听session和application对象
(1)监听session对象的接口是?
HttpSessionListener
HttpSessionAttributeListener
(2)监听session对象的接口的方法分别是?作用 是?
监听session的创建和销毁:HttpSessionListener
sessionCreated(HttpSessionEvent se)
sessionDestroyed(HttpSessionEvent se)
形参:
获取当前被监听到的session对象
监听session作用域数据变更:HttpSessionAttributeListener
attributeAdded(HttpSessionBindingEvent event)
attributeRemoved(HttpSessionBindingEvent event)
attributeReplaced(HttpSessionBindingEvent event)
形参:
获取当前监听到的session中的数据 getName()返回数据的 键名,getValue()返回数据的值
(3)监听application对象的接口是?
ServletContextListener
ServletContextAttributeListener
(4)监听application对象的接口的方法分别是?作用是?
监听application对象的创建和销毁:ServletContextListener
contextInitialized(ServletContextEvent sce)
contextDestroyed(ServletContextEvent sce)
形参:
获取application对象监听application对象的数据的变 更:ServletContextAttributeListener
attributeAdded(ServletContextAttributeEvent event)
attributeRemoved(ServletContextAttributeEvent event)
attributeReplaced(ServletContextAttributeEvent event)
形参:获取当前被监听的数据 getName()返回数据的键名, getValue()返回数据的值
15.监听器案例之当前在线人数统计
(1)根据视频,完成统计当前在线人数功能。
package com.bjsxt.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class MyListener implements HttpSessionListener,ServletContextListener {
//监听application对象
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
//创建计数器
int count=0;
//获取application对象
ServletContext sc = sce.getServletContext();
sc.setAttribute("count", count);
}
//监听session对象
@Override
public void sessionCreated(HttpSessionEvent se) {
//获取application对象中的计数器
ServletContext sc = se.getSession().getServletContext();
int count = (int) sc.getAttribute("count");
//计数器自增
++count;
//存储到application
sc.setAttribute("count", count);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//获取application对象中的计数器
ServletContext sc = se.getSession().getServletContext();
int count = (int) sc.getAttribute("count");
//计数器自减
--count;
//存储到application中
sc.setAttribute("count", count);
}
}
<!-- 配置监听器 -->
<listener>
<listener-class>com.bjsxt.listener.MyListener</listener-class>
</listener>
<div>
<span>当前在线人数为:${applicationScope.count}</span>
</div>