Filter学习笔记

Filter:过滤器

1. 创建Filter

创建一个Java类去实现Filter接口
Filter是Java中预先定义好了的接口,可以过滤不同的内容,具体怎么过滤,需要使用者定义一个实现类,然后实现接口中的过滤方法,在方法中书写过滤的条件。filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行。

@WebFilter("/demo1")  过滤的路径
public class Demo1Filter implements Filter{
//重写init 、doFilter、destroy方法
@Override
	//初始化方法
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("Demo1Filter的init方法执行了");
	}
	@Override
	//doFilter相当于Servlet中的service
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("Demo1Filter的doFilter方法执行了");
		
	}
	@Override
	//销毁方法
	public void destroy() {
		System.out.println("Demo1Filter的destroy方法执行了");
	}
}

Servlet:一个java类去实现Servlet接口,(不推荐这种方式。可以继承抽象类HTTPServlet)
Servlet笔记:(发展历程,生命周期,tomcat匹配url)

2. 过滤器的用途

  • 登录的判断 当你访问网站时,判断你是否进行登录了
  • 权限的判断:判断用户的权限
  • 解决全局post中文乱码问题

3. 生命周期:

1. Servlet

创建:第一次访问该Servlet(单例),执行init
执行:每次访问都会执行service
销毁:服务器关闭时执行destroy

2. Request/Response

创建:请求过来时创建request、response
销毁:对该请求产生响应结束后销毁

3. Session

创建:会话开启,第一次调用request.getSession()
销毁

​ 1、手动调用invalidate()

​ 2、服务器非正常关闭时

​ 3、不操作默认30分钟

4. ServletContext

创建:服务器启动时

销毁:服务器关闭时

5. Filter

创建: 服务器启动时创建,执行的是init方法

执行:访问的路径能匹配上@WebFilter(url),执行doFilter

销毁:服务器关闭时销毁,执行的是destroy方法

注意:修改Servlet代码或Filter代码后,会重新加载环境。同时会销毁Filter并重新初始化。

在这里插入图片描述

4. Filter的执行流程(单个过滤器)

1.根据映射路径匹配到相应的过滤器。
2.执行过滤器的doFilter,进行处理。
3.放行后去匹配请求的资源,没有放行就会被拦截,不请求相应的资源。
4.请求资源结束后,返回过滤器的doFIlter方法,继续执行过滤器内容。
在这里插入图片描述

5. Filter的执行流程(过滤器链,即多个过滤器)

过滤器链:多个过滤器组成的一个整体我们称为过滤器链
我们java代码中,有时需要对同一个请求,进行多次不同业务的过滤,所以我们java代码中需要多个过滤器。只有所有的过滤器都对请求进行了放行,请求才能访问到目标资源,只要多个过滤器中有一个过滤器不放行,那么这个请求都不能够访问到目标资源。 而且,过滤器链中的过滤器是一个一个的执行的,一个过滤器执行完毕之后,会执行下一个过滤器,后面没有过滤器了,才会访问到目标资源。只要其中一个过滤器没有放行,那么这个过滤器后面的过滤器也都不会执行了。
在这里插入图片描述
写三个过滤器,只有名字,和输出内容不同。和一个Servlet
Filter

@WebFilter("/target/*")
public class Demo1Filter implements Filter{
	init destroy 省略
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("demo1Filter 执行:放行前");
		chain.doFilter(request, response);
		System.out.println("demo1Filter 执行:放行后");		
	}
}

Servlet

@WebServlet("/target/demo1")
public class Target1Servlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("目标资源执行了。。。");
		resp.getWriter().append("<h1>Target1Servlet.java</h1>");
	}
}

请求该Servlet,结果如下
在这里插入图片描述

6.过滤器执行细节:

6.1 映射路径

Filter匹配@WebFilter("url") 或 web.xml中的配置文件

  • 精确匹配模式:全路径精确匹配

  • 模糊匹配模式
    目录匹配/admin/* 比如:访问后台管理页面
    扩展名匹配*.action 或者 *.do springmvc时
    匹配所有/* 解决请求响应乱码

Servlet匹配@WebServlet("url") 或 web.xml中的配置文件
精确匹配 > 目录匹配 > 匹配所有/* > 扩展名匹配 > 匹配所有/
在这里插入图片描述

servlet 笔记里有详细的,
https://blog.csdn.net/BigDevil_/article/details/103927442

6.2 Filter拦截方式

默认 只拦截客户端路径(从浏览器直接访问或者重定向)

重定向也相当于从浏览器直接访问,是响应一个304状态码跟url地址,浏览器重新访问给定url

设置拦截方式
  • 设置为只拦截客户端路径(浏览器直接请求)request
    @WebFilter(“url” ,dispatcherTypes = DispatcherType.REQUEST)只拦截客户端路径 (默认)
  • 设置为只拦截请求转发,forward
    @WebFilter(“url” ,dispatcherTypes = DispatcherType.FORWARD)(只拦截请求转发)
  • 拦截 请求转发+客户端路径
    @WebFilter(“url” ,dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
@WebFilter(value="/admin/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
public class Demo1Filter implements Filter{
	...
}

6.3 过滤器链的执行顺序

在这里插入图片描述

  • web module_version 3.0: 用注解方式匹配URL
    和类名的字符大小有关系(越小的越先执行,从第一个字母开始比较,如果第一个字母相同,再比较第二个字母的大小,以此类推)。(理解:根据字母排序,自然排序。

  • web module_version 2.5:用web.xml配置filter,匹配url-pattern
    和web.xml中的配置顺序有关(和类名无关),越靠前的越小执行

案例1:过滤非法字符

form.jsp

<form action="/day18/target" method="get">
		请发表你的言论:<input type="text" name="word"><br>
		<input type="submit" value = "发表">
	</form>

IllegalFilter:

@WebFilter("/target")
public class IllegalFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		//获取发表的内容
		String word = request.getParameter("word");
		//判断里面是否含有非法字符
		for(String str :list) {
			if(word.contains(str)) {
				//含有非法字符
				response.getWriter().write("您发表的言论含有非法字符,请检查后重新发表");
				return;
			}
		}
		//不含有  放行
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	List<String> list = new ArrayList();
	public void init(FilterConfig fConfig) throws ServletException {
		try {
			//读取illegal.txt中的非法字符
			String path = fConfig.getServletContext().getRealPath("");
			path = path + "/illegal.txt";
			BufferedReader br = new BufferedReader(new FileReader(path));
			String str = null;
			while((str = br.readLine()) != null) {
				list.add(str);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

TargetServlet:

@WebServlet("/target")
public class TargetServlet extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//获取发表的言论
		String word = request.getParameter("word");
		response.getWriter().write("发表成功啦!!内容是::"+word);
	}

案例2:解决全站乱码

@WebFilter("/*")
public class EncodingFilter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//解决请求乱码
		request.setCharacterEncoding("utf-8");
		//解决响应乱码
		response.setContentType("text/html;charset=utf-8");
		chain.doFilter(request, response);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值