一、过滤器(Fliter)简介

  过滤器是位于客户端与服务器之间的滤网,在访问资源时会经过一系列的过滤器,

  满足条件则放行,不满足条件的将其拦截。

  

  过滤器可以看做是一个特殊的Servlet,设置了过滤器及其过滤范围后,

  访问处于过滤器过滤范围的资源,会先经过滤器,如果满足过滤条件就会被过滤器放行。

  一系列过滤器的组合称为过滤链,但某一资源满处于多个过滤器的过滤范围时,

  会执行完一个过滤器后进入下一个过滤器,执行顺序和web.xml中的过滤器的配置顺序有关。

  

  过滤器不仅有过滤作用,在过滤过程中可以对调用的请求进行一些操作,

  也可以调用完资源后的响应进行一些操作。

  

二、过滤器实例

  2.1编码过滤

  不适用过滤器进行编码过滤的话,每一个页面都要设置编码格式,这样显然是不方便的。

  使用过滤器和创建Servlet差不多。

  首先我们创建一个Class,然后继承Fliter接口。

  实现里面的init,doFilter,destroy方法,其中init,destroy如无特殊需要可不进行添加或修改。

  主要是里面的deFilter方法,当request或response进入过滤器时,主要是指向doFilter中的内容。

  doFilter方法中携带有一个参数FilterChain chain,FiterChain中还有一个比较重要的方法:

  void javax.servlet.FilterChain.doFilter(ServletRequest request, ServletResponse response)
  //调用过滤链中下一个过滤器,如果后续没有过滤器则访问对应资源

  一般在Filter接口下doFilter()方法里面的FilterChain.doFilter()方法前面为请求过滤,后面为响应过滤。

  

import java.io.IOException;

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.HttpServletResponse; public class SimpleFilter implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
} @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//请求过滤,
request.setCharacterEncoding("utf-8");
     response.setCharacterEncoding("utf-8"); 
System.out.println("Request");
//调用过滤链中后一过滤器,如果后续没有过滤器则访问对应资源。(放行)
chain.doFilter(request, response);
//响应过滤
System.out.println("Response");
} @Override
public void destroy() {
// TODO Auto-generated method stub
} }

这里的过滤器并没有对资源进行过滤,而只是对请求和响应进行了编码格式的改变防止乱码问题。

这里也可以设置满足一定的条件才放行(调用chain.doFilter(.....))。

设置完过滤器后,我们还需要在web.xml中配置过滤器。

配置方法和Servlet大同小异,只是在url地址这一块和Servlet的含义不一样。

<filter>
<filter-name> CharacterFilter</filter-name>
<filter-class>com.filter.SimpleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name> CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

主要是url-pattern中,这里面配置的是过滤器过滤的范围,‘/*’就代表过滤器过滤范围为当前项目下所有资源。

即当前项目下所有资源的reques和respons都要设置为“utf-8”编码格式。

过滤器也可以过滤某一类文件,例如所有的jsp文件,则可以这样写“*.jsp”

这样就代表过滤器范围为该资源下所有.jps文件。

当然也可以指定过滤范围为当前项目下某一部分资源,

例如“/test/*”代表过滤器过滤范围为test文件夹下所有资源。

一个过滤器在web.xml中可以设置多个映射(过滤范围),

这样就可以根据自己要求灵活调整过滤范围。

过滤器的执行顺序是依照web.xml中的配置来的,先经过配置在前面的过滤器,后面的依次通过。

LoginServlet

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.util.HttpPageUtil;; public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
     //输出HTML头部代码
HttpPageUtil.printHtmlPage(out, true);
out.println("<h2>" + username + "李四" + "</h2>");
     //输出HTML尾部代码
HttpPageUtil.printHtmlPage(out, false);
System.out.println("Servlet");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
} }

HTTPUtil

import java.io.PrintWriter;

public class HttpPageUtil {
//打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码
public static void printHtmlPage(PrintWriter out, boolean head) {
if(head) {
out.println("<!DOCTYPE html>\r\n" +
"<html>\r\n" +
"<head>\r\n" +
"<meta charset=\"UTF-8\">\r\n" +
"<title>Insert title here</title>\r\n" +
"</head>\r\n" +
"<body>");
}else {
out.println("</body>\r\n" +
"</html>");
}
}
}

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form name = f1 action ="Filter/Login" method = "post">
username:<input type = "text" name = "username" value = "${un}"></input><br>
password:<input type = "password" name = "password" value = "${pw}"></input><br>
<input type = "submit" value = "登录">
</form>
</body>
</html>

我们来看下控制台输出的信息。

Request
Servlet
Response

我们来分析下整个流程:

首先进入过滤器,执行编码转换,然后输出“Request”,接着放行

执行chain.doFilter();然后进入LoginServlet中输出“Servlet”,

然后再进入过滤器中输出"Response"。

可以看出过滤器的执行流程,就是最开始画的图的流程,

主要注意一点chain.doFilter()前面的是对应客户端到服务器这个方向的,

后面的是chain.doFilter()后面的是服务器到客户端这个方向的。

  2.2登录验证。

  在WebContext目录下新建一个文件夹Page,将要访问的资源文件都放在里面。

  设置一个过滤器,过滤范围为Page文件下所有文件。如果登录则可正常访问

  资源,如果没有登录则跳转到登录界面,并且提示登录。

  

  

LgoinFilter

import java.io.IOException;

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.HttpServletResponse;
import javax.servlet.http.HttpSession; public class LoginFilter implements Filter{ @Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest req = (HttpServletRequest)request;
HttpSession session = req.getSession();
String username = (String)session.getAttribute("username");
//如果Session中已有username则认为已登录,(sesson在LgoinServlet中设置)
if(username != null && ! "".equals(username)) {
System.out.println("LgoinFilterRequest");
//登录则放行
chain.doFilter(request, response);
System.out.println("LgoinFilterResponse");
}else {//反之则重定向到登录页面
request.setAttribute("error", "未登录,无法访问资源!");
//加 / 代表绝对 前缀为localhost:8080
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
} @Override
public void destroy() {
// TODO Auto-generated method stub
}
}

LoginServlet:

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.util.HttpPageUtil;;
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
HttpSession session = request.getSession();
session.setAttribute("username", username);
HttpPageUtil.printHtmlPage(out, true);
out.println("<h2>" + username + "</h2>");
HttpPageUtil.printHtmlPage(out, false);
System.out.println("Servlet");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
} }

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
${error} <form name = f1 action ="/TestServlet/Filter/Login" method = "post">
username:<input type = "text" name = "username" value = "${un}"></input><br>
password:<input type = "password" name = "password" value = "${pw}"></input><br> <input type = "submit" value = "登录">
</form>
</body>
</html>

可以看到没有登录时无法访问资源,登录后可以访问资源。

登录过程中在LoginServlet中创建了session并将用户名放入Session,

访问Page下的资源时过滤器会判断session中是否有用户名,

有用户名则可以访问资源,反之则不能。 

我们来看下能访问资源时控制台输出的信息:(session已被创建)

Request
LgoinFilterRequest
LgoinFilterResponse
Response

客户端访问服务器资源,首先request会经过第一个字符编码过滤器,执行编码格式的转换。

打印出Request,然后放行到LoginFilter过滤器,LoginFilter检测到用户已登录会放行。

由于后续没有过滤器,所以到达访问资源。到达资源后response首先通过LoginFilter

中chain.doFilter()方法后面的语句,打印出LoginFilterResponse,然后执行字符编码过滤器

后面的Response。

执行顺序就是按下图执行的。

参考资料:

https://www.cnblogs.com/xdp-gacl/p/3948353.html

https://www.cnblogs.com/ygj0930/p/6374212.html

  

1.7(学习笔记)过滤器(Fliter)的更多相关文章

  1. JavaWeb学习笔记——过滤器

    JSP可以完成的功能Servlet都可以完成,但是Servlet具备的很多功能是JSP所不具备的. 从使用上来看,Servlet可以分成简单Servlet.过滤Servlet(过滤器)和监听Servl ...

  2. hbase权威指南学习笔记--过滤器

    1.使用hbase是shell客户端进行过滤查询 scan 'testtable',{COLUMNS=>'colfam1:col-0',FILTER=>RowFilter.new(Comp ...

  3. [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. MVC4学习笔记之--身份认证过滤器

    过滤器作为MVC模式中面向切面编程应用很广泛,例如身份验证,日志,异常,行为截取等.博客园里面的大神对应过滤器的介绍以及很多,MVC4中不同的过滤器也介绍得很清楚.FlyDragon  辉太 禁止吸烟 ...

  5. SpringBoot学习笔记(4):添加自定义的过滤器

    SpringBoot:学习笔记(4)——添加自定义的过滤器 引入自定义过滤器 SpringBoot提供的前端控制器无法满足我们产品的需求时,我们需要添加自定义的过滤器. SpringBoot添加过滤器 ...

  6. LevelDB 学习笔记1:布隆过滤器

    LevelDB 学习笔记1:布隆过滤器 底层是位数组,初始都是 0 插入时,用 k 个哈希函数对插入的数字做哈希,并用位数组长度取余,将对应位置 1 查找时,做同样的哈希操作,查看这些位的值 如果所有 ...

  7. Javaweb学习笔记9—过滤器

      今天来讲javaweb的第9阶段学习.   过滤器,我在本次的思维导图中将过滤器和监听器放在一起总结了,监听器比较简单就不单独写了.   老规矩,首先先用一张思维导图来展现今天的博客内容.     ...

  8. jQuery 学习笔记

    jQuery 学习笔记   一.jQuery概述    宗旨: Write Less, Do More.    基础知识:        1.符号$代替document.getElementById( ...

  9. 两千行PHP学习笔记

    亲们,如约而至的PHP笔记来啦~绝对干货! 以下为我以前学PHP时做的笔记,时不时的也会添加一些基础知识点进去,有时还翻出来查查. MySQL笔记:一千行MySQL学习笔记http://www.cnb ...

  10. Ionic2学习笔记(3):Pipe

    作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5538630.html Pipe类似过滤器,比如,在一个字符串要展现在页面之前, 我们需要对这个字符串 ...

随机推荐

  1. Java之戳中痛点 - (3)三目运算符的两个操作数类型尽量一致

    先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...

  2. 金中欢乐赛 C题

    题目传送门 这道题 hash就可以写了 弄了半天有点智障 强行压一压就okay了的说 #include<cstdio> #include<cstring> #include&l ...

  3. mysql 四 表操作

    表介绍 表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段 id,name,qq,age称为字段,其余的,一行内容称为一条记录 本节重点: 1 创建 ...

  4. camera驱动框架分析(中)

    camera host的驱动 下面开始分析camera host吧,如果仅仅是想知道camera sensor驱动怎么写,而不想知道内部具体怎么个调用流程,怎么个架构设计,那可以跳过该部分,直接去看i ...

  5. golang之http

    go获取html页面 package main import ( "fmt" "io/ioutil" "net/http" "ne ...

  6. Linux下文件的三个时间意义及用法

    Linux下文件的三个时间参数: (1)modification time(mtime):内容修改时间        这里的修改时间指的是文件的内容发生变化,而更新的时间. (2)change tim ...

  7. centos7安装tengine强制使用HTTPS访问

    操作系统:centos7.2 x64tengine:Tengine/2.2.0主机IP: 10.0.0.12 一.安装tengine 1.1 下载源码安装包 1.1.1 源码包pcre-8.40   ...

  8. WPF中添加一个文本输入框,按Enter回车,执行绑定的Command

    在WPF+WMMV模式中使用键盘和鼠标事件的绑定代码如下: <TextBox x:Name="SearchBox" Text="{Binding SearchTex ...

  9. JS ajxa请求 返回数据

    1. 发送ajax请求, 后台返回json集合    JQuery: $.each(list集合,回调函数function(下标,集合对象){}); 如下: <script> $(func ...

  10. 病毒&烦人的幻灯片

    <病毒>传送门 <烦人的幻灯片>传送门 病毒 描述 有一天,小y突然发现自己的计算机感染了一种病毒!还好,小y发现这种病毒很弱,只是会把文档中的所有字母替换成其它字母,但并不改 ...