Filter基础

Filter:what?

:   filter是一个过滤器对象,在开发中,浏览器访问服务端的目标资源的时候,它可以进行拦截功能。
:项目中可以定义多个Filter,filter不仅可以拦截请求,还可以拦截响应过程。
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    }
    @Override
    public void destroy() {
    }
}
        filterConfig.getFilterName(); //得到filter的名字
        filterConfig.getInitParameter();//得到filter的属性的值
        filterConfig.getInitParameterNames();//得到filter的属性的名称
        filterConfig.getServletContext();//获取ServletContext对像
        chain.doFilter(request,response);//放行的意思,就是不进行拦截

: 在这里面init()方法:过滤器对象的创建,并且初始化。参数有filterConfig,表示对于filter的配置:有上面几种方法。
: doFilter(): servletRequest和serveltResponse是web服务器或filter链的上一个filter发送过来的请求和响应。而参数chain表示filter链的对象,在MyFilter中的dofilter()方法中调用chain.doFilter(request,response)方法,才可以把请求交给下一个filter链中的filter或者是目标程序。
: destory(): 执行拦截后进行销毁。

filter样例编程

MyServlet

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("hello world");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

MyFilter

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.getWriter().println("hello Filter");
        System.out.println("响应过程");
    }
    @Override
    public void destroy() {
    }
}

web.xml

    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.itcast.chapter.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/MyServlet</url-pattern>
    </servlet-mapping>
    <servlet>
       <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.itcast.chapter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>

运行结果:
在这里插入图片描述

filter的映射

    /*
    * : 使用通配符*,拦截所有的客户请求;
    : <url-pattern>里进行拦截
    : 完全目录匹配:/MyServlet;
    :  目录匹配:/*. /aa/*. 表示拦截aa目录下的所有的请求
    : 扩展名拦截 : *.do *.jsp  错误的写法:/*.co
    * */

filter的请求方式

在配置文件中的,有四个请求方式,默认的是REQUEST,其他FORWARD,INCLUDE,ERROR;

  <filter>
        <filter-name>MyFilter4</filter-name>
        <filter-class>com.itcast.chapter.MyFilter4</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter4</filter-name>
        <dispatcher>FORWARD</dispatcher>
        <url-pattern>/MyServlet1</url-pattern>
    </filter-mapping>

代码:
ForwardServlet:这里面是forward请求,默认的是request请求

public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/first.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

ForwardFilter

public class ForwardFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("响应过程");
    }
    @Override
    public void destroy() {
    }
}

web.xml

 <filter>
        <filter-name>ForwardFilter</filter-name>
        <filter-class>com.itcast.chapter.ForwardFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ForwardFilter</filter-name>
        <url-pattern>/first.jsp</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>ForwardServlet</servlet-name>
        <servlet-class>com.itcast.chapter.ForwardServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ForwardServlet</servlet-name>
        <url-pattern>/ForwardServlet</url-pattern>
    </servlet-mapping>

first.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello ForwardServlet!
</body>
</html>

结果是 hello ForwardServlet!
更改:
web.xml

    <filter>
        <filter-name>ForwardFilter</filter-name>
        <filter-class>com.itcast.chapter.ForwardFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ForwardFilter</filter-name>
        <url-pattern>/first.jsp</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

结果就不会显示。

filter链

web项目中,注册了多个filter,多个filter程序对同一个url进行拦截,那末这些filter称为filter链。
多个过滤器拦截同一个请求,拦截顺序是安在配置文件中的顺序来的。
代码过程:
:MyServlet
: MyFilter1 拦截MyServlet
: MyFilter2 拦截MyServlet
MyServlet

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("hello world <br>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

MyFilter1

public class MyFilter1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.getWriter().println("hello MyFilter1----- before <br/>");
        filterChain.doFilter(servletRequest,servletResponse);
        servletResponse.getWriter().println("hello MyFilter1----- after <br/>");
    }
    @Override
    public void destroy() { }
}

MyFilter2

public class MyFilter2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.getWriter().println("hello MyFilter2----- before <br/>");
        filterChain.doFilter(servletRequest,servletResponse);
        servletResponse.getWriter().println("hello MyFilter2----- after <br/>");
    }
    @Override
    public void destroy() {
    }
}

web.xml

  <filter>
        <filter-name>MyFilter1</filter-name>
        <filter-class>com.itcast.chapter.MyFilter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter1</filter-name>
        <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>MyFilter2</filter-name>
        <filter-class>com.itcast.chapter.MyFilter2</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter2</filter-name>
        <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>

结果:注意他们的顺序,1-brfore,2-before而不是1-brfore,1-after.这是chain.doFilter(resquest,response)起的作用,before代表请求,after代表响应过程
注意他们的顺序,

filterConfig接口

前面已经提到
代码:
MyFilter3

public class MyFilter3 implements Filter {
    String value = "encoding";
    FilterConfig filterConfig;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletResponse.getWriter().println(filterConfig.getInitParameter(value));
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

MyServlet3

public class MyServlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("hello");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

web.xml

    <filter>
    <filter-name>MyFilter3</filter-name>
    <filter-class>com.itcast.chapter.MyFilter3</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
    <filter-name>MyFilter3</filter-name>
    <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>MyServlet1</servlet-name>
        <servlet-class>com.itcast.chapter.MyServlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet1</servlet-name>
        <url-pattern>/MyServlet1</url-pattern>
    </servlet-mapping>

结果是 utf-8
配置属性

  <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>

Listener

what

开发中,可能需要对某些事件进行监听,如监听鼠标点击事件,监听键盘按下事件等,就需要监听器,有四部分组成:

  • 事件:用户的一个操作(如点击一个按钮,调用一个方法等)@ 例如早高峰,发生追尾
  • 事件源:产生事件的对象 @ 车主A 车主B
  • 事件监听器:负责监听发生在事件源上的事件 @ 手机上拍摄的照片或摄像头拍摄的视频
  • 事件处理器:监听器的成员方法,当事件发生的时候,会出发对应的处理器 @ 警察根据相应的责任进行处理
  • 过程
  • 将监听器绑到事件源上,即注册监听器
  • 事件发生时,触发监听器的成员方法,即事件处理器,对事件进行处理。

Servlet监听器有8种

  • 用来监听域对象的创建于销毁
  • 用来监听域对象属性的创建与销毁
  • 用来监听HttpSession域对象中对象的状态,即session中保存的对象的状态。
  • ServletContextListener:
  • HttpSessionListenet
  • ServletRequestListener
  • ServletContextAttributeListener
  • HttpSessionAttributeListener
  • ServletRequestAttributeListener
  • HttpSessionBindingListener:用于监听JavaBean对象绑定到HttpSession对象和从HttpSession对象解绑的事件
  • HttpSessionActivationListener:用于监听HttpSession对象活化和钝化的过程

监听器对象的生命周期

  • 通过监听器对象来监听对象的创建和销毁
  • 监听器对象:在三个域对象之前进行创建,优先于ServletContext对象之前创建
  • ServletContext对象:服务器启动时创建,服务器关闭时销毁
  • Session:一次会话开始时创建,会话结束时销毁。销毁:创建默认时间,服务器关闭,调用invalidate方法。
  • request对象:请求接受时创建,请求结束时销毁。

监听域对象过程

创建一个MyListener
写一个测试的myjsp.jsp的页面

MyListener

package com.yue.chapter08.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyListener implements ServletContextListener, HttpSessionListener,ServletRequestListener{
    public MyListener() {
        System.out.println("MyListener被创建,会执行无参构造方法" );
    }

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象被创建");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContext对象被销毁");

    }

    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("request请求对象被销毁");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("request请求对象被创建了");
    }

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session对象被创建了");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("sesssion对象被销毁了");
    }
}

myjsp.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
这是一个测试监听器的页面
<a href="destory.jsp">session对象的销毁方法</a>
</body>
</html>

destory.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<% session.invalidate();%>
</body>
</html>

web.xml

   <listener>
        <listener-class>com.yue.chapter08.listener.MyListener</listener-class>
    </listener>
    <session-config>
        <session-timeout>2</session-timeout>
    </session-config>

监听域对象属性的过程

testattribute.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%

    session.setAttribute("username","ii");
    session.setAttribute("username","aa");
    session.removeAttribute("username");
    request.setAttribute("username","ii");
    request.setAttribute("username","aa");
    request.removeAttribute("username");

%>

</body>
</html>

MyAttributeListener

public class MyAttributeListener implements ServletContextAttributeListener,HttpSessionAttributeListener, ServletRequestAttributeListener {
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {

    }
    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {

    }
    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {

    }



    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        System.out.println("ServletRequest添加属性:" +name+"="+servletRequestAttributeEvent.getServletRequest().getParameter("name"));
    }
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        System.out.println("ServletRequest替换属性:" +name+"="+servletRequestAttributeEvent.getServletRequest().getParameter("name"));
    }
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
        String name = servletRequestAttributeEvent.getName();
        System.out.println("ServletRequest移除属性:" +name);
    }



    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        System.out.println("httpSession添加属性:" + name +"="+httpSessionBindingEvent.getSession().getAttribute(name) );
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        System.out.println("httpSession移除属性:" + name  );
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        String name = httpSessionBindingEvent.getName();
        System.out.println("httpSession替换属性:" + name +"="+httpSessionBindingEvent.getSession().getAttribute(name) );
    }
}

web.xml

 <listener>
        <listener-class>com.yue.chapter08.attribute.MyAttributeListener</listener-class>
    </listener>

开发中,监听域对象属性用到的较多。

为什么使用PHP管理crontab 一般在定时任务较少的情况下,使用原生的crontab服务一般不会有什么问题,但当定时任务较多时就会产生如下问题: 文本形式的定时任务可读性很差,在没有任何注释的情况下,新人很难在不读源码的情况下了解定时任务的业务逻辑 在分布式的场景中,定时任务会散落到多台机器上,无法统一管理 定时任务的日志不能集中化管理,对定时任务的运行分析及故障排除比较麻烦 基于以上几点原因,我们迫切的需要一个可以集中化管理的、可配置的定时任务管理器 但自己开发一套分布式的定时任务系统何其复杂,所以作者采用crontab服务做辅助,使用php实现对定时任务的配置管理 使用php管理定时任务有哪些优势 定时任务可以不再是以文本方式的形式存在,可以存储在缓冲、数据库中,甚至你可以开发管理功能,在后台对定时任务进行编辑 定时任务的日志是可配置的,你可以按照业务需求,对日志进行差异化配置 使用方式如下: 编写一个任务管理器,可参考test/simple.php 将上述脚本添加到crontab中,一分钟执行一次 示例: <?php $crontab_config = [  'test_1' => [  'name' => '服务监控1',  'cmd' => 'php -v',  'output' => '/tmp/test.log',  'time' => '* * * * *'  ],  'single_test' => [  'name' => 'php -i',  'cmd' => 'php -i',  'output' => '/tmp/single_script.log',  'time' => [  '* * * * *',  '* * * * *',  ],  ], ];  $crontab_server = new \Jenner\Zebra\Crontab\Crontab($crontab_config); $crontab_server->start(); 工具短小,但很精悍 在分布式场景中,你可以把定时任务写入数据库中进行统一管理,你可以设定哪些定时任务是由哪些机器执行, 然后通过生成文本文件的方式发送到所有机器上,再由这些机器上的phpCrontab读取处理;从而实现分布式场景下的定时任务统一管理。 标签:Zebra
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值