20210715_过滤器和监听器


内容
1.过滤器
2.监听器

一、过滤器

一、Filter的工作流程

过滤器是一个驻留在服务器端的Web组件,可以截取用户端和资源之间的请求和响应信息,并对信息进行过滤
Day24过滤器和监视器 - 图1

1. 过滤器的组成

  1. 过滤源,请求url的配置
  2. 所有符合规则的数据交互行为,过滤规则,doFilter中进行编写
  3. 过滤结果

    2.创建一个过滤器

    a) 实现javax.servlet.Filter接口
    1) void destroy(); 销毁,再服务器关闭时调用,释放filter占用的资源
    2)void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;过滤规则,自动执行的过滤代码,我们需要自定义的部分,如果符合过滤规则,则通过chain放行,如果不符合规则,则做出处理
    3)void init(FilterConfig filterConfig) throws ServletException;在服务器启动时自动调用,初始化Filter
    b)进行注册,可以通过注册文件的形式或者配置文件的形式(web.xml);

  4. web.xml文件中进行注册

  5. <filter>
  6. <filter-name>my</filter-name>
  7. <filter-class>filter.MyFilter</filter-class>
  8. <!-- 初始化参数的设置 -->
  9. <init-param>
  10. <param-name>charset</param-name>
  11. <param-value>utf-8</param-value>
  12. </init-param>
  13. </filter>
  14. ``
  15. <filter-mapping>
  16. <filter-name>my</filter-name>
  17. <url-pattern>/*</url-pattern>
  18. </filter-mapping>
  19. ``
  20. 注解的方式
  21. @WebFilter(value="/*",initParams=@WebInitParam(name="charaset" ,value="utf-8"))

区别:
1). web.xml中相对比较写法繁琐一些,注解简单一点;
2). web.xml中后期可以随时更改,注解因为编译后为字节码文件,后期不容易修改

3.生命周期

Day24过滤器和监视器 - 图2
描述的时候,当tomcat重新启动,是才进行销毁

4.多个过滤器同时存在

当有多个过滤器存在时,主要看url部分,范围大的先进行,范围小的后进入。
Day24过滤器和监视器 - 图3
先进的后出;形成了一个链。

5.通过过滤器完成请求中的乱码处理

  1. @WebFilter(value="/*",initParams=@WebInitParam(name="charaset" ,value="utf-8"))//过滤所有
  2. //filter.MyFilter
  3. public class MyFilter implements Filter{
  4. private String str="utf-8";
  5. ``
  6. @Override
  7. public void init(FilterConfig filterConfig) throws ServletException {
  8. //获取到配置参数
  9. str=filterConfig.getInitParameter("charset")!=null?filterConfig.getInitParameter("charset"):str;
  10. }
  11. ``
  12. //在doFilter编写过滤规则
  13. @Override
  14. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  15. throws IOException, ServletException {
  16. request.setCharacterEncoding(str);
  17. chain.doFilter(request, response);//代表放行,不会到目标资源去
  18. ``
  19. }
  20. @Override
  21. public void destroy() {
  22. ``
  23. }
  24. ``
  25. }

    6.通过过滤器完成认证

    核心代码如下

  26. @WebFilter(value= {"/html/*","/dept/*","/emp/*"})//这些请求都会进入到该过滤器

  27. public class LoginAuthenticationFilter implements Filter{
  28. /**
  29. * 只有登录才放行,没有登录,跳转到登录页面
  30. */
  31. @Override
  32. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  33. throws IOException, ServletException {
  34. HttpServletRequest req=(HttpServletRequest) request;
  35. HttpServletResponse resp=(HttpServletResponse) response;
  36. String lname= (String) req.getSession().getAttribute("lname");
  37. if("admin".equals(lname)) {
  38. chain.doFilter(request, response);
  39. }else {
  40. //req.getRequestDispatcher("/index.html").forward(req, response);
  41. resp.sendRedirect("/emp_sys_v2.0/index.jsp");
  42. }
  43. }

    三、监听器

    Listener 用于监听 java web程序中的事件,例如创建、修改、删除Session、request、context等,并触发响应的事件。
    Listener 对应观察者模式,事件发生的时候会自动触发该事件对应的Listener。 Listener 主要用于对 Session、request、context 进行监控。servlet2.5 规范中共有 8 种Listener
    不同功能的Listener 需要实现不同的 Listener 接口,一个Listener也可以实现多个接口,这样就可以多种功能的监听器一起工作。
    8种监听器可以分为三类:
    监听 Session、request、context 的创建与销毁,分别为 HttpSessionListener、ServletContextListener、ServletRequestListener
    监听对象属性变化,分别为: HttpSessionAttributeListener、ServletContextAttributeListener、ServletRequestAttributeListener
    监听Session 内的对象,分别为HttpSessionBindingListener 和 HttpSessionActivationListener。与上面六类不同,这两类 Listener 监听的是Session 内的对象,而非 Session 本身,不需要在 web.xml中配置。
    1.实现的步骤
    1)实现对应的接口
    2)注册
    使用配置文件

  44. <listener>

  45. <listener-class>listener.ApplicationListener</listener-class>
  46. </listener>

    使用注解

  47. @WebListener

    使用监听器完成在线人数的统计

    1)使用jsp页面作为欢迎页面
    2)监听器代码

  48. @WebListener

  49. public class OnLineCount implements HttpSessionListener{
  50. ``
  51. @Override
  52. public void sessionCreated(HttpSessionEvent se) {
  53. //获取到application对象
  54. ServletContext application=se.getSession().getServletContext();
  55. //获取到数据apllication对象中的值
  56. int count=application.getAttribute("count")==null?0:(Integer)application.getAttribute("count");
  57. //数量增加
  58. count++;
  59. application.setAttribute("count", count);
  60. ``
  61. }
  62. ``
  63. @Override
  64. public void sessionDestroyed(HttpSessionEvent se) {
  65. //数量减少
  66. ServletContext application=se.getSession().getServletContext();
  67. //获取到数据apllication对象中的值
  68. int count=(Integer)application.getAttribute("count");
  69. //数量增加
  70. count--;
  71. application.setAttribute("count", count);
  72. ``
  73. }

3)是在主页后者登录页面显示:${count}

使用监听器完成配置文件的读取

  1. 因为使用MyBatis框架是需要读取配置文件,读文件比较耗时,希望在项目启动时执行MyBatis中的静态代码块执行文件的读取
  2. ``
  3. @WebListener
  4. public class ApplicatListener implements ServletContextListener{
  5. ``
  6. @Override
  7. public void contextDestroyed(ServletContextEvent sce) {
  8. // TODO Auto-generated method stub
  9. ``
  10. }
  11. ``
  12. @Override
  13. public void contextInitialized(ServletContextEvent sce) {
  14. //System.out.println("读文件的操作");
  15. //读取mybatis的相关配置文件,执行MyBatisUtil中的静态代码块
  16. // MyBatisUtil.session;
  17. try {
  18. //Class.forName就执行类的静态代码块的
  19. Class.forName("com.woniu.emp_sys.util.MyBatisUtil");
  20. } catch (ClassNotFoundException e) {
  21. e.printStackTrace();
  22. }
  23. ``
  24. }
  25. ``
  26. }