1.过滤器技术
1.1.filter简介
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理
1.2.filter快速入门
步骤:
新建一个过滤器
1 2
| public class Demo1Filter implements Filter{ }
|
实现接口中尚未实现的方法(着重实现doFilter方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Demo1Filter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException { }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("过滤器执行了....."); }
public void destroy() { }
}
|
在web.xml中进行配置(主要是配置要对哪些资源进行过滤)
1 2 3 4 5 6 7 8
| <filter> <filter-name>filterdemo</filter-name> <filter-class>com.yueqian.filter.Demo1Filter</filter-class> </filter> <filter-mapping> <filter-name>filterdemo</filter-name> <url-pattern>
|
仔细观察:
但是servlet程序没有去执行!
因为,servlet程序在执行的时候,被filter拦截了,需要进行放行!
1 2 3 4 5 6 7 8
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("过滤器执行了....."); chain.doFilter(request, response); }
|
再次观察效果:
再仔细观察一个细节,客户端请求服务端,是先走的filter,再走的servlet程序!
1.3.filter执行流程原理
1.4.filter中API详解
1.4.1.filter生命周期
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
doFiltr(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法
destory():代表是filter销毁方法 当filter对象销毁时执行该方法
Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁
1.4.2.filter中的API
1)init(FilterConfig)
其中参数config代表 该Filter对象的配置信息的对象,内部封装是该filter的配置信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public void init(FilterConfig filterConfig) throws ServletException { String filterName = filterConfig.getFilterName(); System.out.println("filterName:"+filterName); String initValue = filterConfig.getInitParameter("aaa"); System.out.println("initValue:"+initValue); ServletContext servletContext = filterConfig.getServletContext(); }
|
2)destory()方法
filter对象销毁时执行
3)doFilter方法
doFilter(ServletRequest,ServletResponse,FilterChain)
其中的参数:
ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。
FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
思考:如果在doFilter方法中使用response和request中一些方法,我们应该怎么办呢?
思考:为何先执行filter1,后执行filter2呢?
1.5.filter配置详解
1 2 3 4 5 6 7 8
| <filter> <filter-name>bbb</filter-name> <filter-class>comm.yueqian.filter.FilterDemo2</filter-class> </filter> <filter-mapping> <filter-name>bbb</filter-name> <url-pattern>
|
url-pattern配置时
1)完全匹配 /sertvle1
2)目录匹配 /com/controller/* —-最多的
/jsp/*–匹配jsp的资源
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
3)扩展名匹配 *.java *.jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转是执行filter
总结Filter的作用?
1)公共代码的提取
整个网站的字符编码问题
登录功能的判断
2)可以对request和response中的方法进行增强(装饰者模式/动态代理)
3)进行权限控制
1.6.filter案例
解决乱码问题
处理post请求乱码问题
1 2 3 4 5 6 7
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); chain.doFilter(request, response); }
|
案例:
模拟淘宝,购物商场中如果没有登录时不可以查看,购物车,订单,是直接跳转到登录页面
思考:那些页面不用执行这个过滤器?:首页,登录页面,注册?如何将这三个页面踢掉,也就是过滤器不起作用
代码:
\1) 定义一个登陆过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| HttpServletRequest httpRequest=(HttpServletRequest)request; HttpServletResponse httpResponse=(HttpServletResponse) response; HttpSession session=httpRequest.getSession(); String username=(String) session.getAttribute("username"); String path=httpRequest.getRequestURI(); if(path.indexOf("/head.jsp")!=-1) { chain.doFilter(request, response); return; } if(path.indexOf("/login.jsp")!=-1) { chain.doFilter(request, response); return; } if(path.indexOf("/register.jsp")!=-1) { chain.doFilter(request, response); return; } if(username!=null) { chain.doFilter(request, response); }else { httpResponse.sendRedirect(httpRequest.getContextPath()+"/login.jsp"); }
|
\2) 配置xml文件
1 2 3 4 5 6 7 8 9
| <!-- 用户登录过滤 --> <filter> <filter-name>FilterServlet3</filter-name> <filter-class>com.shop.FilterServlet3</filter-class> </filter> <filter-mapping> <filter-name>FilterServlet3</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
|
3)登陆的servlet
1 2 3 4 5 6 7
| String username=request.getParameter("username"); HttpSession session=request.getSession(); session.setAttribute("username", username); response.sendRedirect(request.getContextPath()+"/head.jsp");
|
4)head.jsp
1 2 3 4 5 6 7 8 9
| <h1> <a href="">首页</a> 欢迎:${username } <hr/> </h1> <a href="${pageContext.request.contextPath}/login.jsp">登录</a> <a href="${pageContext.request.contextPath}/register.jsp">注册</a> <a href="${pageContext.request.contextPath}/buycar.jsp">购物车</a> <a href="${pageContext.request.contextPath}/order.jsp">订单</a>
|
2. 监听器技术
javaEE包括13门规范 在课程中主要学习 servlet技术 和 jsp 技术
其中 servlet规范包括三个技术点:servlet listener filter
2.1.监听器简介
监听器就是监听某个对象的的状态变化的组件
监听器的相关概念:
事件源:被监听的对象(女朋友) —– 三个域对象 request session servletContext
监听器:监听事件源对象 事件源对象的状态的变化都会触发监听器 —- 6+2
注册监听器(将监听器安装在你女朋友身上):将监听器与事件源进行绑定
响应行为:监听器监听到事件源的状态变化时 所涉及的功能代码 —- 程序员编写代码
2.2.监听器有哪些
2.3.监听三大域对象2
2.3.1.ServletContextListener
监听器三步曲:
1)创建一个类去实现接口
1 2
| public class Demo1Listren implements ServletContextListener{ }
|
2)覆盖其中的2个方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Demo1Listren implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized..........."); }
public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed..........."); }
}
|
3)配置监听器对象
1 2 3 4 5
| <!--注册监听器 -->
<listener> <listener-class>linstern.Demo1Listren</listener-class> </listener>
|
观察打印:
- 销毁
监听器的方法参数
1 2 3 4 5 6 7 8 9 10 11 12
| public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized..........."); ServletContext servletContext = sce.getServletContext(); ServletContext servletContext2 = (ServletContext) sce.getSource(); }
|
ServletContextListener监听器的主要作用
a、初始化的工作:初始化对象 初始化数据 —- 加载数据库驱动 连接池的初始 化
b、加载一些初始化的配置文件 — spring的配置文件
c、任务调度—-定时器—-Timer/TimerTask
2.3.2. HttpSessionListener
思考:在页面请求一个jsp页面,sessionCreated会不会执行呢?
1 2 3
| public void sessionCreated(HttpSessionEvent se) { System.out.println("HttpSessionEvent............"+se.getSession().getId()); }
|
既然我们都知道session在我们服务端会有很多很多个,那么我现在换一个浏览器,sessionCreated会不会再次调用呢?
会调用
HttpSession对象的生命周期
何时创建:第一次调用request.getSession时创建
何时销毁:服务器关闭销毁 session过期 手动销毁
思考:session监听器有啥用呢?
2.3.3. ServletRequestListener
ServletRequest的生命周期
创建:每一次请求都会创建request
销毁:请求结束
步骤:
1)创建一个类 实现 接口
1 2
| public class MyHttpRequestLis implements ServletRequestListener{ }
|
2)覆盖其中的方法
1 2 3 4 5 6 7 8 9
| public class MyHttpRequestLis implements ServletRequestListener{ public void requestInitialized(ServletRequestEvent sre) { System.out.println("requestInitialized............"); } public void requestDestroyed(ServletRequestEvent sre) { System.out.println("requestDestroyed..........."); } }
|
3)配置
1 2 3 4
| <!-- 配置request监听器 --> <listener> <listener-class>linstern.MyHttpRequestLis</listener-class> </listener>
|
2.4.监听三个域对象的属性变化
域对象的通用的方法:
setAttribute(name,value)
— 触发添加属性的监听器的方法
— 触发修改属性的监听器的方法
getAttribute(name)
removeAttribute(name)
— 触发删除属性的监听器的方法
ServletContextAttibuteListener监听器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ServletContextAttibuteLis implements ServletContextAttributeListener{
public void attributeAdded(ServletContextAttributeEvent scab) { System.out.println("添加属性了:"+scab.getName()+":"+scab.getValue()); }
public void attributeRemoved(ServletContextAttributeEvent scab) { System.out.println("删除属性了:"+scab.getName()+":"+scab.getValue()); } public void attributeReplaced(ServletContextAttributeEvent scab) { System.out.println("修改属性了:"+scab.getName()+":"+scab.getValue()); }
}
|
1 2 3
| <listener> <listener-class>linstern.ServletContextAttibuteLis</listener-class> </listener>
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); servletContext.setAttribute("name", "tom"); servletContext.setAttribute("name", "lucy"); servletContext.removeAttribute("name"); }
|
HttpSessionAttributeListener监听器(同上)
ServletRequestAriibuteListenr监听器(同上)