Filter过滤器
来源:互联网 发布:云计算判断题 编辑:程序博客网 时间:2024/06/04 22:53
Filter的基本功能是对servlet容器调用servlet的过程进行拦截,从而在servlet进行响应处理的前后实现一些特殊的功能。
在servletAPI中定义了三个接口类来供开发人员编写filter程序:Filter,FilterChain,FilterConfig。
Filter程序是一个实现了Filter接口的JAVA类,与servlet程序相似,它由servlet容器进行调用和执行。
Filter程序需要在web.xml文件中进行注册和设置它所能拦截的资源:Filter程序可以拦截Jsp,Servlet,静态图片文件和静态HTML文件。
Filter的基本工作原理:
当在web.xml注册了一个Filter来对某个servlet程序进行拦截处理时,这个Filter就成了servlet容器与该servlet程序的通信线路上的一道关卡,该Filter可以对servlet容器发送给servlet程序的请求和servlet程序回送给servlet容器的相应内容进行拦截,可以决定是否将请求继续传递给servlet程序,以及对请求和相应信息是否进行修改。
在一个web应用程序中可以注册多个filter程序,每个filter程序都可以对一个或一组servlet程序进行拦截。
若有多个Filter程序对某个servlet程序的访问过程进行拦截,当针对该servlet的访问请求到达时,web容器将把这多个Filter程序组合成Filter链(过滤器链)。Filter链中各个Filter的拦截顺序与它们在应用程序 web.xml中映射的顺序一致。
简单Filter实例:
新建两个页面,实现跳转:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <a href="two.jsp">to two.jsp</a></body></html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h2>TWO</h2></body></html>实现filter接口:
package com.sa.filter;import javax.servlet.*;import java.io.IOException;public class HelloFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("doFilter"); } @Override public void destroy() { System.out.println("destroy"); }}在web.xml中配置filter:
<filter> <filter-name>helloFilter</filter-name> <filter-class>com.sa.filter.HelloFilter</filter-class> </filter> <filter-mapping> <filter-name>helloFilter</filter-name> <url-pattern>/pages/filter/two.jsp</url-pattern> </filter-mapping>
测试:
Filter相关API:
Filter接口:
public void init(FilterConfig filterConfig) throws ServletException :类似于servlet的init方法,在创建filter对象后,立即执行,且只执行一次。filter对象在servlet容器加载当前web应用时被创建。该方法用于对当前的filter进行初始化操作,Filter实例是单例的。FilterConfig类似于ServletConfig,可以在web.xml文件中,配置当前filter的初始化参数。
<filter> <filter-name>helloFilter</filter-name> <filter-class>com.sa.filter.HelloFilter</filter-class> <init-param> <param-name>name</param-name> <param-value>sasa</param-value> </init-param> </filter> <filter-mapping> <filter-name>helloFilter</filter-name> <url-pattern>/pages/filter/two.jsp</url-pattern> </filter-mapping>
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException :真正的filter逻辑代码需要编写在该方法中。每次拦截都会调用该方法。
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("doFilter"); //放行 filterChain.doFilter(servletRequest,servletResponse); }
FilterChain:Filter链,多个Filter构成一个Filter链。把请求传给Filter链中的下一个Filter,若当前Filter是Filter链的最后一个,将把请求给到目标Servlet或JSP。多个filter拦截的顺序和<filter-mapping> 配置的顺序有关,靠前的先被调用。public void destroy():销毁释放当前filter所占用的资源,在filter销毁之前被调用,且只被调用一次。
实现登录拦截:
login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>登录</title></head><body><h2>${msg}</h2> <form action="<%=request.getContextPath()%>/pages/filter/hello.jsp" method="post"> name:<input type="text" name="name"> pwd:<input type="text" name="pwd"> <input type="submit" value="提交"> </form></body></html>hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h1>hello:{param.name}></h1></body></html>NameFilter:
package com.sa.filter;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class NameFilter implements Filter{ private FilterConfig filterConfig; @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig=filterConfig; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { String name=request.getParameter("name"); String name1=filterConfig.getInitParameter("name"); if (!name.equals(name1)) { request.setAttribute("msg", "名字错辣"); request.getRequestDispatcher("/pages/filter/login.jsp").forward(request,response); return; } else { filterChain.doFilter(request, response); } } @Override public void destroy() { }}
PwdFilter:
package com.sa.filter;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class PwdFilter implements Filter{ private FilterConfig filterConfig; @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig=filterConfig; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { String pwd=request.getParameter("pwd"); String pwd1=filterConfig.getServletContext().getInitParameter("pwd"); if (!pwd.equals(pwd1)) { request.setAttribute("msg", "密码错辣"); request.getRequestDispatcher("/pages/filter/login.jsp").forward(request,response); return; } else { filterChain.doFilter(request, response); } } @Override public void destroy() { }}
配置web.xml:
<filter> <filter-name>nameFilter</filter-name> <filter-class>com.sa.filter.NameFilter</filter-class> <init-param> <param-name>name</param-name> <param-value>sasa</param-value> </init-param> </filter> <filter-mapping> <filter-name>nameFilter</filter-name> <url-pattern>/pages/filter/hello.jsp</url-pattern> </filter-mapping> <filter> <filter-name>pwdFilter</filter-name> <filter-class>com.sa.filter.PwdFilter</filter-class> </filter> <filter-mapping> <filter-name>pwdFilter</filter-name> <url-pattern>/pages/filter/hello.jsp</url-pattern> </filter-mapping> <context-param> <param-name>pwd</param-name> <param-value>123</param-value> </context-param>
测试:
Dispatcher元素:指定过滤器所拦截的资源被servlet容器调用的方式,可以是request,include,forword,error之一,默认为request,可以设置多个<dispatcher>子元素来指定filter对资源的多种调用方式进行拦截。
①:request:当用户直接访问页面时,web容器将会调用过滤器,如果目标资源是通过requestDispatcher的include()或forWord()方法访问则不会触发过滤器。
通过get或post请求直接访问。
②:forword:如果目标资源是通过requestDispatcher的forword()方法访问时,那么该过滤器将会被调用,除此之外,该过滤器不会被调用。
或<jsp:forword page=""/> 或通过page指令的errorPage转发页面,<%@page errorPage="error.jsp"%>
③:include:如果目标资源是通过requestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
或<jsp:include file="/..." />
④:error:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
在web.xml文件中通过error-page节点声明
测试:
现在想通过两种方式访问two.jsp:一种是通过request请求,一种是通过forword请求。
one.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><script> function a() { window.location.href="<%=request.getContextPath()%>/pages/1011/two.jsp"; }</script><head> <title>one</title> <button onclick="a();" >request</button></head><body></body></html>two.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>two</title></head><body> <h1>this is two</h1></body></html>three.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>three</title></head><body> <a href="four.jsp">forword</a></body></html>four.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>four</title></head><body> <jsp:forward page="two.jsp"></jsp:forward></body></html>
filter1:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("Filter1"); chain.doFilter(req, resp); }
filter2:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("Filter2"); chain.doFilter(req, resp); }
配置xml:
<filter> <filter-name>Filter1</filter-name> <filter-class>com.sa.filter.Filter1</filter-class> </filter> <filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/pages/1011/two.jsp</url-pattern> </filter-mapping> <filter> <filter-name>Filter2</filter-name> <filter-class>com.sa.filter.Filter2</filter-class> </filter> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/pages/1011/two.jsp</url-pattern> </filter-mapping>
通过request访问two.jsp:
通过forword访问two.jsp:
可以得知filter的默认监视请求方式是request。
修改xml文件:
<filter> <filter-name>Filter1</filter-name> <filter-class>com.sa.filter.Filter1</filter-class> </filter> <filter-mapping> <filter-name>Filter1</filter-name> <url-pattern>/pages/1011/two.jsp</url-pattern> </filter-mapping> <filter> <filter-name>Filter2</filter-name> <filter-class>com.sa.filter.Filter2</filter-class> </filter> <filter-mapping> <filter-name>Filter2</filter-name> <url-pattern>/pages/1011/two.jsp</url-pattern> <dispatcher>FORWARD</dispatcher> </filter-mapping>通过request访问two.jsp:
通过forword访问two.jsp:
- 过滤器Filter
- 过滤器Filter
- Filter 过滤器
- 过滤器 filter
- 过滤器filter
- 过滤器,Filter
- 过滤器Filter
- filter--过滤器
- 过滤器Filter
- filter过滤器
- Filter过滤器
- filter过滤器
- Filter过滤器
- Filter过滤器
- Filter 过滤器
- Filter过滤器
- Filter(过滤器)
- filter过滤器
- linux 防火墙设置、访问ip限制、iptables命令
- Android 图片选择到裁剪之步步深坑
- C语言提高-第5讲: 函数的参数(回文、素数)
- 一个介绍YOLO的特别好的网址
- 360安全卫士企业版卸载
- Filter过滤器
- 3_python入门前100个小程序
- 让DIV中的垂直滚动条自动滚到最底部
- Linux集群管理员应对审计的7个小窍门
- gitlab和github使用ssh方式拉取代码的配置
- Decision Tree(决策树)
- MATLAB作图总结
- Java Applet 基础
- 17092401_CentOS7(64)下Oracle11g创建实例及win7下Oracle客户端连接