黑马程序员技术交流社区

标题: 【石家庄校区】学习笔记-Listener&Filter [打印本页]

作者: htb52110    时间: 2017-12-15 22:31
标题: 【石家庄校区】学习笔记-Listener&Filter
本帖最后由 htb52110 于 2017-12-15 22:36 编辑

Listener&Filter

1、监听器:
概念:
监听器:就是一个Java类,用来监听其他的JAva的状态的变化
作用:
用来监听其他的对象的变化的
主要应用在图形化界面中比较多
GUI         android
术语:
事件源:指的是被监听的对象
监听器:指的是监听的对象
事件源与监听器的绑定:
事件:指的是事件源的改变。

2、WEB中的监听器
分为三类八种(监听三个域对象)
事件源:Servlet中的三个域对象
监听器:自定义类实现8个接口
事件源和监听器的绑定:配置
2.1、WEB中的监听器的分类
三类八种:
一类:监听三个域对象的创建和销毁的监听器:
    ServletContextListener
    HttpSessionListener
    ServletRequestListener
二类:监听三个域对象的属性变更的监听器(属性添加,移除,替换):
    ServletContextAttributeListener
    HttpSessionAttributeListener
    ServletRequestAttributeListener
三类:监听HttpSession中的JavaBean的状态改变(绑定,解除绑定,钝化,活化)
    HttpSessionBindingListener
    HttpSessionActivationListener

2.1.1、 ServletContextListener:监听ServletContext对象的创建和销毁:

2.1.1.1、方法:

2.1.1.2、ServletContext对象何时创建和销毁
创建:服务器启动的时候,服务器为每个WEB应用创建一个属于该web项目的对        象ServletContext.
销毁:服务器关闭或者项目从服务器中移除的时候.
2.1.1.3、企业中的应用:
加载框架的配置文件      :Spring框架 ContextLoaderListener
定时任务调度:                    : Timer        TimerTask

2.1.2、HttpSessionListener:监听HttpSession的创建和销毁的监听器:
2.1.2.1、方法:

2.1.2.2、HttpSession何时创建和销毁的
创建:
服务器端第一次调用getSession();
销毁:
      非正常关闭服务器(正常关闭session会序列化):
      session过期了默认30分钟.
      手动调用session.invalidate();
2.1.2.3、HttpSession的问题
访问Servlet会不会创建Session   : 不会
访问JSP会不会创建Session       :会.
访问html会不会创建Session      :不会
2.1.3、 ServletRequestListener:监听ServletRequest对象的创建和销毁的监听器:
2.1.3.1、方法:

2.1.3.2、request对象何时创建和销毁
创建:客户端向服务器发送一次请求,服务器就会创建request对象.
销毁:服务器对这次请求作出响应后就会销毁request对象.
                     2.1.3.3、问题
访问一个Servlet会不会创建request对象:会
访问一个JSP会不会创建request对象:会
访问一个HTML会不会创建request对象:会
2.2.1、  ServletContextAttributeListener:监听ServletContext对象的属性变更:
2.2.1.1、方法:

2.2.2、  HttpSessionAttributeListener:监听HttpSession中的属性变更:
2.2.2.1、方法:

2.2.3、 ServletRequestAttributeListener:监听ServletRequest对象的属性变更的:
2.2.3.1、方法:


2.3.1、 HttpSessionBindingListener:监听HttpSession中的JavaBean的绑定和解除绑定的
2.3.1.1、方法:

2.3.2、HttpSessionActivationListener:监听HttpSession中的JavaBean的钝化和活化的.
2.3.2.1、方法:

2.3.2.2、
sessionDidActivate();      :--活化(反序列化)
sessionWillPassivate();   :--钝化(序列化到硬盘)
                     2.3.2.3、 优化Session:
             * 通过配置<Context>标签配置定时session序列化.
         * 在tomcat/conf/context.xml中配置<Context>                       :在tomcat中所有的虚拟主机和虚拟路径都会按照这个配置执行.
         * 在tomcat/conf/Catalina/localhost/context.xml配置<Context> :在tomcat中的localhost虚拟主机中的所有虚拟路径按照这个配置执行.
         * 在当前的工程下的META-INF/context.xml配置<Context>               :当前这个工程按照配置执行.
配置文件:
<Context>
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
        <Store className="org.apache.catalina.session.FileStore" directory="it315"/>
</Manager>
</Context>


注意:第三类监听器很特殊,,不需要进行配置的.作用在JavaBean上的监听器.JavaBean可以自己感知到在Session中的状态.

3、Filter
3.1、Filter的概念
可以过滤从客户端想服务器发送的请求。
3.2、Filter的用途
进行IP的过滤,脏话过滤,自动登录,权限的分配,响应压缩。。。
3.3、使用过滤器
a、新建一个类,实现Filter的接口
b、在web.xml里进行配置,形式和servlet的配置信息类似
<filter>
     <filter-name>FilterDemo</filter-name>
    <filter-class>com.itheima.filter.FilterDemo</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>FilterDemo</filter-name>
    <url-pattern>/demo1.jsp</url-pattern>
(路径里边具体路径就是对该路径进行过滤,所有请求过滤写【/*】)
  </filter-mapping>
3.3、过滤器的生命周期
3.3.1、过滤器的创建和销毁
创建:服务器启动的时候创建过滤器对象
销毁:服务器关闭的时候,或者项目移出的时候。
3.3.2、FilterConfig过滤器的配置对象

3.4、FilterChain过滤器链
过滤器链中的过滤器的执行的顺序与<filter-mapping>的配置顺序有关.
FilterChain doFilter(request,response); 放行,放行到下一个过滤器,如果没有下一个过滤器,到大目标资源
3.5、Filter相关的配置
3.5.1、 <url-pattern>的配置(拦截的路径):
完全路径匹配        :以 / 开始  /demo4/demo1.jsp
目录匹配                : 以 / 开始 以 * 结束.  /*  /demo1/*
扩展名匹配            :不能以 / 开始 以 * 开始.  *.do  *.action

3.5.2、 <servlet-name>的配置:
根据Servlet的名称拦截Servlet.
3.5.3、  <dispatcher>的配置(拦截的方式):
* REQUEST           :默认值.
* FORWARD           :转发.
* INCLUDE           : 包含.
* ERROR             : 错误页面跳转.(全局错误页面)

3.6、增强Request中的getparameter方法
继承                 :控制这个类构造.
装饰者模式   :增强的类和被增强类实现相同的接口,增强的类中获得到被增强的类的引用.
* 缺点:接口中方法太多.
动态代理     :被增强的类实现接口就可以.



附件:利用装饰者模式进行增强Request中的getparameter()方法的代码demo

package cn.itcast.demo6;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
* 解决get和post请求 全部乱码
*
* @author 姜涛
*
*/
public class GenericEncodingFilter implements Filter {

        @Override
        public void destroy() {
        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain) throws IOException, ServletException {
                // 转型为与协议相关对象
                HttpServletRequest httpServletRequest = (HttpServletRequest) request;
                // 对request包装增强
                HttpServletRequest myrequest = new MyRequest(httpServletRequest);
                chain.doFilter(myrequest, response);
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }

}

// 自定义request对象
class MyRequest extends HttpServletRequestWrapper {

        private HttpServletRequest request;

        private boolean hasEncode;

        public MyRequest(HttpServletRequest request) {
                super(request);// super必须写
                this.request = request;
        }

        // 对需要增强方法 进行覆盖
        @Override
        public Map getParameterMap() {
                // 先获得请求方式
                String method = request.getMethod();
                if (method.equalsIgnoreCase("post")) {
                        // post请求
                        try {
                                // 处理post乱码
                                request.setCharacterEncoding("utf-8");
                                return request.getParameterMap();
                        } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                        }
                } else if (method.equalsIgnoreCase("get")) {
                        // get请求
                        Map<String, String[]> parameterMap = request.getParameterMap();
                        if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                                for (String parameterName : parameterMap.keySet()) {
                                        String[] values = parameterMap.get(parameterName);
                                        if (values != null) {
                                                for (int i = 0; i < values.length; i++) {
                                                        try {
                                                                // 处理get乱码
                                                                values = new String(values
                                                                                .getBytes("ISO-8859-1"), "utf-8");
                                                        } catch (UnsupportedEncodingException e) {
                                                                e.printStackTrace();
                                                        }
                                                }
                                        }
                                }
                                hasEncode = true;
                        }
                        return parameterMap;
                }

                return super.getParameterMap();
        }

        @Override
        public String getParameter(String name) {
                Map<String, String[]> parameterMap = getParameterMap();
                String[] values = parameterMap.get(name);
                if (values == null) {
                        return null;
                }
                return values[0]; // 取回参数的第一个值
        }

        @Override
        public String[] getParameterValues(String name) {
                Map<String, String[]> parameterMap = getParameterMap();
                String[] values = parameterMap.get(name);
                return values;
        }

}

作者: wheat    时间: 2017-12-15 23:27
很不错哦

作者: 尹哈哈哈    时间: 2017-12-16 08:41
谢谢分享,谢谢楼主
作者: 观棋忘语    时间: 2017-12-16 19:07
谢谢分享!666666666

作者: 小石姐姐    时间: 2017-12-20 11:13
厉害了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2