菜鸟教程  传送门

  

  过滤器Filter::JavaWeb三大组件之一,它与Servlet很相似,过滤器是用来拦截请求的,而不是处理请求的

  当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

过滤器Filter生命周期

package com.Gary.filter;

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.annotation.WebFilter; @WebFilter("/*")
public class GaryFilter implements Filter { public GaryFilter() {
System.out.println("过滤器-构造方法");
} public void destroy() {
System.out.println("过滤器-destroy()");
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
System.out.println("过滤器-doFilter()");
} public void init(FilterConfig fConfig) throws ServletException {
System.out.println("过滤器-init()");
} }

GaryFilter.java

  init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;

   doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(<url->pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;

  destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

  @WebFilter("/*")表示过滤全部的请求

  @WebFilter("/login.jsp")表示过滤登录的请求

  每发起一个请求过滤器都会调用一次doFilter()【通常都是对请求进行过滤,对请求过滤放到chain.doFilter(request, response)上边】

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("过滤器-请求前");
chain.doFilter(request, response);
System.out.println("过滤器-请求后");
}

  当过滤登录请求时可先指定路径@WebFilter("/login.jsp*")后,修改doFilter()方法,用户访问login.jsp时页面重定向到index.jsp

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
//当访问login.jsp时页面请求重定向
((HttpServletResponse)response).sendRedirect("index.jsp");
}

  通过Web.xml中配置

<!--   注册    告诉web有哪些filter并告诉其路径 -->
<filter>
<filter-name>xxx</filter-name>
<filter-class>com.Gary.filter.GaryFilter</filter-class>
</filter> <!-- filter映射 -->
<filter-mapping>
<filter-name>xxx</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>指定一个过滤器。
<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。
在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher>子元素可以设置的值及其意义
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

web.xml配置各节点说明

过滤器的应用场景:

  (一)执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;

  (二)通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

  (三)在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;

  (一)【静态】当编码通过静态设置时可直接放到过滤器doFilter()中

//    HttpServletRequest ServletRequest
// HttpServletRequest ServletResponse
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//对编码进行过滤 类型为ServletResponse
request.setCharacterEncoding("utf-8");
chain.doFilter(request, response);
}

  (一)【动态】当编码通过动态设置时需放到Web.xml中

<!--   注册    告诉web有哪些filter并告诉其路径 -->
<filter>
<filter-name>xxx</filter-name>
<filter-class>com.Gary.filter.EncodeFilter</filter-class>
<init-param>
<param-name>Encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter> <!-- filter映射 -->
<filter-mapping>
<filter-name>xxx</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

  (一)过滤器中init()初始化编码类型

    private String encoding;

    public void init(FilterConfig fConfig) throws ServletException {
encoding = fConfig.getInitParameter("Encoding");
}

  (二)doFilter()中设置权限管理过滤  完整项目代码

  Web,xml中配置过滤器映射

  <filter>
<filter-name>AdminFilter</filter-name>
<filter-class>com.Gary.filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<!-- 访问admin目录下文件做权限过滤 -->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>

  实现过滤器中的doFilter,isAdmin对用户是否是管理员进行判断,管理员返回值为True

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpReq = (HttpServletRequest)request;
HttpServletResponse httpResp = (HttpServletResponse) response;
Object o = httpReq.getSession().getAttribute("user");
if(o==null) {
httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
}else {
User u = (User)o;
if(u.isAdmin()) {
// 对权限进行放行
chain.doFilter(request, response);
}else {
// 重定向回首页
httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Gary04</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>AdminFilter</filter-name>
<filter-class>com.Gary.filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<!-- 访问admin目录下文件做权限过滤 -->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
</web-app>

web.xml

package com.Gary.filter;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.Gary.model.User; //@WebFilter("/AdminFilter")
public class AdminFilter implements Filter { public AdminFilter() {
// TODO Auto-generated constructor stub
} public void destroy() {
// TODO Auto-generated method stub
} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest)request;
HttpServletResponse httpResp = (HttpServletResponse) response;
Object o = httpReq.getSession().getAttribute("user");
if(o==null) {
httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
}else {
User u = (User)o;
if(u.isAdmin()) {
// 对权限进行放行
chain.doFilter(request, response);
}else {
// 重定向回首页
httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
}
}
} /**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
} }

AdminFilter.java

总结

Filter的三个方法

  void init(FilterConfig):在Tomcat启动时被调用;

  void destroy():在Tomcat关闭时被调用;

  void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;

FilterConfig类:与ServletConfig相似,用来获取Filter的初始化参数

  ServletContext getServletContext():获取ServletContext的方法;

  String getFilterName():获取Filter的配置名称;

  String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;

  Enumeration getInitParameterNames():获取所有初始化参数的名称。

FilterChain类

  void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行

各拦截方式:REQUEST、FORWARD、INCLUDE、ERROR,默认是REQUEST方式

  REQUEST:拦截直接请求方式

  FORWARD:拦截请求转发方式

  INCLUDE:拦截请求包含方式

  ERROR:拦截错误转发方式

  <filter>
<filter-name>DispatcherFilter</filter-name>
<filter-class>com.Gary.filter.DispatcherFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DispatcherFilter</filter-name>
<url-pattern>/dispatcher1.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

JavaWeb_初识过滤器Filter的更多相关文章

  1. Angularjs在控制器(controller.js)的js代码中使用过滤器($filter)格式化日期/时间实例

    Angularjs内置的过滤器(filter)为我们的数据信息格式化提供了比较强大的功能,比如:格式化时间,日期.格式化数字精度.语言本地化.格式化货币等等.但这些过滤器一般都是在VIEW中使用的,比 ...

  2. 网站过滤器Filter

    实际上,Filter与Servlet及其相似,区别只是FIlter的doFilter()方法里多了一个FilterChain的参数,通过该参数可以控制是否放行用户的请求.网站有了过滤器十分的方便,可以 ...

  3. paip.输出内容替换在Apache 过滤器filter的设置

    paip.输出内容替换在Apache 过滤器filter的设置 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog ...

  4. java Servlet中的过滤器Filter

    web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  5. [ionic开源项目教程] - 第6讲 过滤器filter的使用

    过滤器filter的使用 1.回顾 再熟悉一下tab1.html的代码: <div class="list"> <a ng-repeat="item i ...

  6. selvert的过滤器filter处理中文乱码

    注意问题:在学习用selvert的过滤器filter处理中文乱码时,在filter配置初始化时用了utf-8处理中文乱码,而在提交的jsp页面中却用了gbk.虽然两种都可以出来中文乱码,但是却造成了处 ...

  7. MVC之 自定义过滤器(Filter)

    MVC之 自定义过滤器(Filter) 一.自定义Filter 自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttri ...

  8. Servlet中的过滤器Filter用法

    1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应. 主要用于对HttpServletRequest 进行预处理,也可以对Http ...

  9. Servlet中的过滤器Filter详解

    加载执行顺序 context-param->listener->filter->servlet web.xml中元素执行的顺序listener->filter->stru ...

随机推荐

  1. 简单的shell练习

    1.判断/etc/inittab文件是否大于100行,如果大于,则显示”/etc/inittab is a big file.”否者显示”/etc/inittab is a small file.”# ...

  2. golang substring

    在java下习惯了String.subString(start,end) 然后再golang继续敲substring木有了,看了下代码,也是原生支持的 但是百度发现有些人竟然把字符串转成字符数组再根据 ...

  3. 分布式---Paxos算法

    5.Paxos   Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致.一个典型的场景就是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点执行相同的操作序列,那么他们最 ...

  4. C# 面向对象7 命名空间

    命名空间 **namespace(命名空间),用于解决类重名问题,可以看作"类的文件夹" **如果代码和被使用的类在一个namespace则不需要using **在不同命名空间下的 ...

  5. python发起post请求获取json数据使用requests方法

    最普通的答案 我一直就觉得GET和POST没有什么除了语义之外的区别,自打我开始学习Web编程开始就是这么理解的 . 可能很多人都已经猜到了答案是: 1.GET 使用URL或Cookie传参.而POS ...

  6. oracle存储过程临时表

    接到一个以前领导的需求,说的大概意思是: 如果能关联上就取关联上的最大值更新到表里,没有关联上的就取原来的值. 写一个存储过程,这正好用到了临时表,上网查询,用的太乱了,特别记录. 准备阶段 创建PD ...

  7. 基于Chromium的浏览器已上线通用“显示密码”按钮

    基于Chromium的Edge在日前发布的Canary通道版本中,对用户界面进行了优化调整从而让InPrivate窗口变得更加简洁.在今天获得的版本更新中,微软继续带来了隐私相关的新内容--实现通用的 ...

  8. 防sql注入方法

    mysql_escape_string(strip_tags($arr)) /** * 函数名称:post_check() * 函数作用:对提交的编辑内容进行处理 * 参 数:$post: 要提交的内 ...

  9. centos7安装kong和kong-dashboard

    1.安装Kong yum install -y https://kong.bintray.com/kong-community-edition-rpm/centos/7/kong-community- ...

  10. 基于初始种子自动选取的区域生长(python+opencv)

    算法中,初始种子可自动选择(通过不同的划分可以得到不同的种子,可按照自己需要改进算法),图分别为原图(自己画了两笔为了分割成不同区域).灰度图直方图.初始种子图.区域生长结果图.另外,不管时初始种子选 ...