• 1. JAVA WEB开发实战经典第5章 过滤器和监听器Java Web程序设计
  • 2. 过滤器的基本概念 过滤器是在Servlet 2.3之后增加的新功能,当需要限制用户访问某些资源或者在处理请求时提前处理某些资源的时候,就可以使用过滤器完成。 过滤器是以一种组件的形式绑定到WEB应用程序当中的,与其他的WEB应用程序组件不同的是,过滤器是采用了“链”的方式进行处理的。
  • 3. 实现过滤器 在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法: public void init(FilterConfig config) throws ServletException 初始化方法,做资源的初始化工作 public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException 客户请求与过滤器相关联的URL时,执行该方法 public void destroy() 过滤器销毁时执行该方法,来释放过滤器申请的资源
  • 4. FilterChain FilterChain接口的主要作用是将用户的请求向下传递给其他的过滤器或者是Servlet: 在FilterChain接口中依然定义了一个同样的doFilter()方法,这是因为在一个过滤器后面可能存在着另外一个过滤器,也可能是请求的最终目标(Servlet),这样就通过FilterChain形成了一个“过滤链”的操作。 public void doFilter(ServletRequest request,ServletResponse response) throws IOException,ServletException
  • 5. 过滤器的应用 —— 编码过滤 在进行WEB开发中,编码过滤是必不可少的操作,如果按照之前的做法,在每一个JSP或者是Servlet中都重复编写“request.setCharacterEncoding(“UTF-8”)”的语句,这样会造成大量的代码重复,那么此时就可以通过过滤器完成这种编码过滤。 步骤 编写login.jsp,提供输入数据的表单 编写LoginServlet.java,接收参数 编写EncodingFilter.java实现编码过滤 在web.xml文件中配置EncodingFilter.java
  • 6. 编码过滤器 -- EncodingFilter.javapackage com.filter; public class EncodingFilter implements Filter { private String encoding=null; public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding(encoding); chain.doFilter(req, res); } public void init(FilterConfig config) throws ServletException { this.encoding=config.getInitParameter("encoding"); } }
  • 7. 配置web.xml文件 encoding com.filter. EncodingFilter encoding UTF-8 encoding /*
  • 8. 登陆验证 登陆验证是所有WEB开发中不可缺少的部分,最早的做法是在每个页面通过验证session的方式来判断用户是否登录,但是如果每个页面都这样做的话,则肯定会造成大量的代码重复,而通过过滤器的方式就可以避免这种重复的操作。 在这里需要注意的是,session本身是属于HTTP协议的范畴,但是doFilter()方法中定义的是ServletRequest类型的对象,那么要想取得session,则必须进行向下转型,将ServletRequest变为HttpServletRequest接口对象,才能够通过getSession()方法取得session对象。
  • 9. 登录验证步骤 编写login.jsp 编写LoginServlet.java判断登录信息是否正确 在web.xml文件中配置LoginServlet.java 编写LoginFilter.java过滤未登录用户 在web.xml文件中配置LoginFilter.java
  • 10. 登陆验证—LoginFilter.javapackage com.filter; public class LoginFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; HttpSession session=req.getSession(); if(session.getAttribute("username")!=null){ chain.doFilter(req, res); }else{ session.setAttribute("message", "只有登录之后才可以访问系统"); res.sendRedirect(req.getContextPath()+"/login.jsp"); } } public void init(FilterConfig filterConfig) throws ServletException {} }
  • 11. 登录验证---web.xml LoginServlet com.filter.LoginFilter LoginServlet /file/*
  • 12. 监听器概念 监听器是一个实现了某一特定接口的普通Java类 该类专门用于监听某一特定Java对象的方法调用或属性改变事件 当被监听对象发生上述事件后,监听器某个方法将立即被执行而做出相应的动作或者反应 事件源 ServletContext、HttpSession、ServletRequest这三个作用域对象
  • 13. 监听器接口ServletContext对象监听器接口 ServletContextListener用来监听Web应用程序生命周期的监听器接口 ServletContextAttributeListener是监听ServletContext对象中属性改变的监听器接口
  • 14. 监听器接口ServletContext监听器接口监听接口方法说明ServletContextListenerpublic void contextInitialized( ServletContextEvent sce)在Web应用程序启动初始化后调用该方法,一般用来实现应用程序资源的准备工作public void contextDestroyed( ServletContextEvent sce)在Web应用程序即将结束销毁前调用该方法,一般用来实现释放应用程序资源的工作ServletContextAttributeListenerpublic void attributeAdded( ServletContextAttributeEvent scab) 当ServletContext对象中属性增加时调用该方法public void attributeRemoved( ServletContextAttributeEvent scab)当ServletContext对象中属性被删除时调用该方法public void attributeReplaced( ServletContextAttributeEvent scab)当ServletContext对象中属性值被改变时调用该方法
  • 15. 监听器接口HttpSession对象监听器接口 HttpSessionListener是用来监听会话对象生命周期的监听器接口 HttpSessionAttributeListener是用来监听会话对象属性改变的监听器接口 HttpSessionBindingListener是用来监听会话对象的对象绑定监听器接口 HttpSessionActivationListener是用来监听会话对象的对象迁移监听器接口
  • 16. 监听器接口HttpSession对象监听器接口监听接口方法说明HttpSessionListenerpublic void sessionCreated( HttpSessionEvent se)当HttpSession对象创建时执行该方法public void sessionDestroyed( HttpSessionEvent se)当HttpSession对象销毁时执行该方法HttpSessionAttributeListenerpublic void attributeAdded( HttpSessionBindingEvent se)当HttpSession对象中属性增加时调用该方法public void attributeRemoved( HttpSessionBindingEvent se)当HttpSession对象中属性被删除时调用该方法public void attributeReplaced( HttpSessionBindingEvent se)当HttpSession对象中属性值被改变时调用该方法HttpSessionBindingListenerpublic void valueBound( HttpSessionBindingEvent event)当实现HttpSessionBindingListener接口的属性对象被加入HttpSession时调用该方法public void valueUnbound( HttpSessionBindingEvent event)当实现HttpSessionBindingListener接口的属性对象从HttpSession对象中移除时调用该方法HttpSessionActivationListenerpublic void sessionDidActivate( HttpSessionEvent se) 当HttpSession对象要从一个服务器迁移至另一个服务器后,就会对所有属性对象作反序列化,此时会调用该方法public void sessionWillPassivate( HttpSessionEvent se)当HttpSession对象要从一个服务器迁移至另一个服务器时,必须先在原来的服务器上序列化HttpSession对象中所有的属性对象,此时会调用该方法
  • 17. 监听器接口ServletRequest对象监听器接口 ServletRequestListener是用来监听HttpServletRequest生命周期的监听器接口 ServletRequestAttributeListener是用来监听ServletRequest对象中属性改变的监听器接口
  • 18. 监听器接口ServletRequest对象监听器接口监听接口方法说明ServletRequestListenerpublic void requestInitialized( ServletRequestEvent sce)在ServletRequest对象生成时调用该方法public void requestDestroyed( ServletRequesttEvent sce)在ServletRequest对象即将结束销毁前调用该方法ServletRequestAttributeListenerpublic void attributeAdded( ServletRequestAttributeEvent scab) 当ServletRequest对象中属性增加时调用该方法public void attributeRemoved( ServletRequestAttributeEvent scab)当ServletRequest对象中属性被删除时调用该方法public void attributeReplaced( ServletRequestAttributeEvent scab)当ServletRequest对象中属性值被改变时调用该方法
  • 19. 监听器开发创建相应的监听器类 实现相应接口、覆盖相应的方法 在web.xml中配置监听器类 包+类名
  • 20. 监听器开发实例---在线人数统计创建响应的监听器类 监听Session对象的创建与销毁, 新建一个集合对象。创建一个Session对象则将其加入到集合对象中,销毁一个session对象则将其从集合中删除,最后统计集合中元素个数,也就是Session的个数,也即在线人数个数 该集合能被所有用户使用,所以要将集合对象保存到ServletContext作用域中
  • 21. 监听器开发实例---在线人数统计public void sessionCreated(HttpSessionEvent event) { HttpSession session=event.getSession(); ServletContext context=session.getServletContext(); HashSet sessions=(HashSet)context.getAttribute("sessions"); if(sessions==null){sessions=new HashSet();} sessions.add(session); context.setAttribute("sessions", sessions); } public void sessionDestroyed(HttpSessionEvent event) { HttpSession session=event.getSession(); ServletContext context=session.getServletContext(); HashSet sessions=(HashSet)context.getAttribute("sessions"); if(session!=null){sessions.remove(session);} context.setAttribute("sessions", sessions); }