1.Filter_概述
过滤器是用来干嘛的?
当浏览器访问服务器的资源(Servlet)时,过滤器可以把这个请求拦截下来,做统一的操作
****************
请求到达资源之前会拦截一次(使用);
响应到达浏览器之前还会拦截一次;
2.Filter_快速入门
过滤器的使用步骤?
1.自定义类,实现Filter接口,并且重写抽象方(init,doFilter,destroy)
2.在类上通过@WebFilter("/*")设置拦击路径
3.测试。
filterChain.doFilter(servletRequest,servletResponse);是什么意思?
放行
3.Filter_细节_web.xml配置方式
思考:
如果web.xml和注解都配置了相同的filter,会有什么效果?
共同对servlet进行过滤/
4.Filter_细节_执行流程&生命周期
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println(“filterdemo2…请求执行…”);
chain.doFilter(req, resp);
System.out.println(“filterdemo2…响应执行…”);
}
浏览器请求 localhost:8080/index.jsp;
问题:
System.out.println("filterdemo2...请求执行....");
System.out.println("filterdemo2...响应执行....");
init方法什么时候执行?
服务器启动,创建Filter对象后就执行;执行一次
destroy方法什么时候执行?
服务器正常关闭之前,执行,执行一次
doFilter:
每拦截到一次请求,就会执行;
5.Filter_细节_过滤器拦截路径配置
@WebFilter("/user/")这样配置会拦截什么?
能拦截到 /user及其子路径
@WebFilter(".jsp")这样配置会拦截什么?
只能拦截jsp文件;
6.Filter_细节_过滤器拦截方式配置(了解)
拦截方式:
REQUEST:浏览器直接请求(默认)
FORWARD:转发
INCLUDE:包含
ERROR:错误
ASYNC:异步请求;
7.Filter_细节_过滤器链(多个过滤器)
@WebFilter("/")
public class AcFilter implements Filter {}
@WebFilter("/")
public class AbFilter implements Filter {}
以上配置过滤器,如果访问/day18/FirstServlet这个资源,执行顺序?
<filter>
<filter-name>demo9</filter-name>
<filter-class>cn.itcast.filter.FilterDemo9</filter-class>
</filter>
<filter-mapping>
<filter-name>demo9</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>demo8</filter-name>
<filter-class>cn.itcast.filter.FilterDemo8</filter-class>
</filter>
<filter-mapping>
<filter-name>demo8</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
以上配置过滤器,如果访问/day18/FirstServlet这个资源,执行顺序?
先执行FilterDemo8 后执行FilterDemo9 ,根据字符串的
8.Filter_案例1_登录验证_分析
判断一个用户是否登录的依据?
在session域中获取user对象,如果能获取出来,则已登录,如果获取不出来,则没有登录;
哪些资源不需要做登录验证?
登录相关的都不需要:
jsp;
js;
css;
图片;
servlet;
9.Filter_案例1_登录验证_代码实现
如何获取请求的资源路径?
哪些资源是不需要过滤的?
10.Filter_案例2_过滤敏感词汇_分析
一次请求中,默认情况下,过滤器的request对象和Servlet资源中拿到的request的对象是不是同一个?
是!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*************************************
使用静态代理完成敏感词汇过滤:
1.真实对象;
2.代理对象;
代理对象自己不能搞,找真实对象来搞,并且对方法进行了增强;
3.用户使用时真正使用的是代理对象;
代理对象和被代理对象(真实对象)使用方式(调用的方法)是一致的:
要求代理对象和被代理对象要实现同样的接口
请求URL
http://localhost/day12/messageServlet?message=你是个傻子吧?傻子傻子傻子
// 自定义MyHttpServletRequest 实现 HttpServletRequest 接口,完成对于 getParameter方法的优化
```java
/**
* @PackageName: live.longmarch.web.servlet
* @ClassName: MyHttpServletRequest
* @Author: gaoning
* @Date: 2019/11/12 20:30
* @Description: // 需要代理request的功能,则需要和request实现同一个接口
*/
public class MyHttpServletRequest implements HttpServletRequest {
// 通过构造方法传递真实request对象过来。
public MyHttpServletRequest(HttpServletRequest request) {
this.request = request;
}
// 创建一个真实的request。 我不重写的方法,让他继续保持原样
private HttpServletRequest request;
// 重写getParameter方法,
@Override
public String getParameter(String s) {
// 在方法内部替换敏感字符
// 判断参数中有没有敏感字符,有的话进行替换
String parameter = request.getParameter(s);
parameter = parameter.replaceAll("傻子", "小可爱");
return parameter;
}
// 访问的资源路径
```java
@WebServlet("/messageServlet")
public class MessageServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(request);
// 输出message 的请求参数的值
String message = request.getParameter("message");
System.out.println(message);
}
过滤器
@WebFilter("/*")
public class MessageFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// 获取所有的请求参数,如果请求参数中有傻子,替换为我爱你
// 将req强转为request对象
// 真实对象
HttpServletRequest request = (HttpServletRequest) req;
// 创建自己的代理request对象,将代理传入getParameter方法中。
// 需要代理request的功能,则需要和request实现同一个接口
MyHttpServletRequest proxy = new MyHttpServletRequest(request);
// 将重写过的proxy传给servlet,
System.out.println(proxy);
chain.doFilter(proxy, resp);
}
11_Filter_案例2_过滤敏感词汇_分析
一次请求中,默认情况下,过滤器的request对象和Servlet资源中拿到的request的对象是不是同一个?
是!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*************************************
使用静态代理完成敏感词汇过滤:
1.真实对象;
2.代理对象;
代理对象自己不能搞,找真实对象来搞,并且对方法进行了增强;
3.用户使用时真正使用的是代理对象;
代理对象和被代理对象(真实对象)使用方式(调用的方法)是一致的:
要求代理对象和被代理对象要实现同样的接口
12_动态代理1_基本实现步骤
代理模式的作用?
代理模式的实现方式?
动态代理一个真实对象的实现步骤?
Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h);
3个参数分别是什么意思?
ClassLoader loader:类加载器-固定写法:真实对象.getClass().getClassLoader();
Class<?>[] interfaces:真实对象实现的接口数组-固定书写:真实对象.getClass().getInterfaces();
InvocationHandler h:处理器-固定书写:new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
}}
--------------------------------------------------
当使用代理对象调用任何方法时,InvocationHandler中的invoke方法都会执行!!
--------------------------------------------------
InvocationHandler的抽象方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
}
3个参数分别是什么意思?
proxy:代理对象(不用)
method:使用代理对象调用的是哪个方法,那么method的描述的就是哪个方法;
args:使用代理对象调用方法时传递的参数;
13_动态代理2_增强方法
增强真实对象的方法,可从哪些方面增强该方法?
1.参数;
2.返回值;
3.方法体;
14_Filter_案例2_过滤敏感词汇_实现
敏感词汇文件读进内存的操作在哪里进行?
在init方法中进行加载
15_Listener_概述
ServletContextListener监听的是谁?监听的是ServletContext的创建和销毁;
contextDestroyed(ServletContextEvnet sce)方法什么时候被调用?
ServletContext被销毁时调用
contextInitialized(ServletContextEvnet sce)方法什么时候调用?
ServletContext被创建时调用
16_Listener_ServletContextListener使用
ServletContextLister在web.mxl中的配置方式和注解配置方式?
web.xml:
cn.itcast.web.listener.ContextLoaderListener
注解:
@WebListener
如何在web.xml中配置资源文件的路径信息?
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
如何获取配置文件中的参数信息?
ServletContext:
getInitParameter(String name);
**********************************************
1.ServletContextListener中的代码会随着web项目的启动和关闭而自动执行;
2.在ServletContextListener中,可以通过ServletContext对象,获取web.xml中配置的初始参数
