A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Itleizhihao 初级黑马   /  2019-9-26 15:32  /  888 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

web的三大组件:
        Servlet
编写步骤:
        1.写一个类实现Servlet接口
        2.重写抽象方法
        3.配置
                注解配置 @WebServlet
                web.xml中配置
                <sevlet>
                        <servelet-name>别名
                        <servelet-class>群类名
                </sevlet>
                <servlet-mapping>
                <servlet-name>
                <url-pattern>
                </servlet-mapping>
声明周期:
        init() 初始化.只执行一次.
                两种方式:
                        默认是第一次访问的时候执行.
                        在<servlet-mapping>中<load-on-startup> 如果是负数.就是第一次访问的时候执行
                        如果是0或者正数.就是服务器启动时执行.
        service()  每一次访问都会执行
        destroy()  只执行一次. 服务器关闭的时候执行.
       
        Filter
        Listener
```

## Filter

```java
生活中的过滤器: 相当于一个比较贪婪的土匪. 海关.
web中的过滤器: 就是去过滤请求和响应.
作用:
        1.权键验证.
        2.敏感词过滤.字符集的指定.
       
编写的步骤:
        1.写一个类去实现Filter接口
        2.重写方法
                doFilter
                        FilterChain的对象去放行.
        3.去配置(拦截的路径)
                1.注解 @WebFilter
                2.web.xml中去配置.
                <filter>
                        <filter-name>别名
                        <filter-class>群类名
                </filter>
                <filter-mapping>
                <filter-name>
                <url-pattern>
                </filter-mapping>
               
        注意:
                千万不要用注解和web.xml去重复配置一个Filter.否则就会执行两次这个Filter
               
执行流程:
        前提:请求的url匹配上Filter配置的拦截路径.
        如果匹配上了.会优先执行Filter中doFilter中的逻辑.
        在doFilter方法中.如果FilterChain去放行.就可以访问对应的访问资源.
        再去中放行后的逻辑.

生命周期方法:
        init() 只执行一次. 并且只能在服务器启动的时候执行.
        注意:跟Servlet中就不同了.
        Servlet中可以去配置他的执行时机
                Servlet就相当一一个开店的.有两个选择开门时间.
                        1.一大早.就开门.等着客户上门.
                        2.尽情的睡懒觉. 直到第一个顾客上门.
                Filter 就是一个土匪.  必须一大早就拦在路上.等你的拦截对象(只能是服务器启动的时候就执行init方法.)
                               
        doFilter()  每次拦截都执行
        destroy()  执行一次. 服务器关闭的时候执行.
       
拦截路径的配置: 跟Servlet的资源路径配置规则一样
        1.完全路径匹配  /user/demoServlet
        2.目录匹配    /user/*
        3.后缀名匹配  *.jsp   注意这里没有斜杆
        4.全部匹配  /*


/**/
拦截方式的配置
        1.注解中配置  dispacherTypes
                        request 默认值.从浏览器中直接访问.
                        forward  转发
        2.web.xml中配置
        <filter-mapping>  
                <dispacher>

过滤器链
        一次请求的URL匹配上多个Filter.这多个Filter都会执行.就叫做过滤器链.
        执行流程:  Filter1  Filter2
        Filter1放行前的代码
        Filter2放行前的代码
        资源代码
        Filter2放行后的代码
        Filter1放行后的代码
                有点类似于我们java中的栈.

过滤器链中的doFilter是如何执行的.
        在第一个过滤器的doFilter中.如果我们用FilterChain放行了. filterChain.doFilter().
        在执行filterChain的doFilter方法的时候.他回去判断.是否还有下一个匹配的过滤器.如果有就会去执行下一个Filter的doFilter方法.如果没有.就回去执行资源逻辑.
               
过滤器链中过滤器的顺序:
        1.用注解的方式配置的过滤器.  过滤器的执行顺序跟过滤器的名字中字符的先后顺序有关.
        2.如果web.xml中配置的过滤器. 只跟<filter-mapping>的先后顺序有关.
        2.如果一个过滤器用注解配置的.一个是在web.xml中配置的.执行的顺序是怎么样的?
                在web.xml中配置的过滤器先执行.
               
注意:
        如果在过滤器链中任意的一个过滤器中不去放行. 那么后续的过滤器都不会执行.
        或者反过来说. 要想正常访问某个资源.必须所有的过滤器都放行.
       


```

## 登录验证

```
1.要将request对象强转成 HttpServletRequest
2. 要将登录相关的资源排除掉. 包括web文件夹下所有的文件夹
3. 去判断是否登录.
        如果已经登录.就放行
        如果没有登录就跳转到登录界面.
       
       
```

## 动态代理

```java
真实对象: 就是被代理的对象.
代理对象: 就是我们去实现的跟被代理对象相同功能的一个对象.但是具体到每个方法可能不一致.这个不一致我们叫做"增强"
代理: 就是用代理对象去替代真实对象去执行对应的逻辑.就叫做代理.

1.JDK提供的动态代理的api
        Proxy
前提: 真实对象跟代理对象必须实现相同的接口.

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h)
loader:就是类加载器. 真实对象.getClass().getClassLoader()
interfaces:就是真实对象实现的所有的方法. 真实对象.getClass().getInterfaces()
h:是一个回调接口.

InvocationHandler

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}
proxy:就是代理对象.一般不用.
method: 就是当前代理对象调用的方法封装成的对象.
args:就是调用当前方法,需要传入的参数.

2.cglib
使用步骤:
        1.导包  spring-core就可以了
       
         Lenovo le = new Lenovo();
        //1.创建一个增强器对象
        Enhancer en = new Enhancer();
        //2. 设置父类
        en.setSuperclass(le.getClass());
        //3.设置回调函数
        en.setCallback(new MethodInterceptor() {
            /**
             *
             * @param o  代理对象
             * @param method 代理对象调用的当前方法封装成的对象
             * @param args  调用当前方法传入的参数
             * @param methodProxy 方法代理对象
             * @return
             * @throws Throwable
            
               methodProxy.invokeSuper(o,args);  传的第一个参数是代理对象
               method.invoke(le, money); 第一个参数传的是真实对象.
             */
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //判断是否是sale方法
                if(method.getName().equals("sale")){
                    //1.增强参数
                    double money = (double) args[0];
                    money = money * 0.85;
                    System.out.println("专车接你....");
                    //使用真实对象调用该方法
                    String obj = (String) method.invoke(le, money);
                    System.out.println("免费送货...");
                    //2.增强返回值
                    return obj+"_鼠标垫";
                }else{
                    Object obj = method.invoke(le, args);
                    return obj;
                }
            }
        });
        //4.创建代理对象
        Lenovo o = (Lenovo) en.create();
//        o.sale(8000);
        o.show();
```

## FileReader源码分析

```java
FileReader{
public FileReader(String fileName) throws FileNotFoundException {
        super(new FileInputStream(fileName));
    }
  }
  
InputStreamReader{
public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

}


StreamDecoder{
   
      public static StreamDecoder forInputStreamReader(InputStream var0, Object var1, String charset) throws UnsupportedEncodingException {
        String var3 = charset;
        if (charset == null) {
            var3 = Charset.defaultCharset().name();
        }
      }
}

Charset{
    public static Charset defaultCharset() {
        if (defaultCharset == null) {
            synchronized (Charset.class) {
                String csn = AccessController.doPrivileged(
                    new GetPropertyAction("file.encoding"));
                Charset cs = lookup(csn);
                if (cs != null)
                    defaultCharset = cs;
                else
                    defaultCharset = forName("UTF-8");
            }
        }
        return defaultCharset;
    }
}

默认编码格式跟file.encoding有关系.
   
    http://bbs.itheima.com/forum.php ... d=462695&extra=
建议:
        每次牵涉到编码集的时候.我们都手动指定.不要使用默认的编码集.因为不同的启动方式.是有可能不同的.
        
```

## Listener(了解)

```
监听:
        就是关心的某个事件发生的时候.会触发对应的代码.
应用场景:
        1.监听域对象的创建和销毁: reqeust, session ,application(ServletContext)
        2.监听域对象中值的存入: session
        4.监听session的钝化和活化
        ServletContextListener

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马