Filter过滤器

淩亂°似流年 2022-06-07 04:08 413阅读 0赞

Filter的基本功能是对servlet容器调用servlet的过程进行拦截,从而在servlet进行响应处理的前后实现一些特殊的功能。

在servletAPI中定义了三个接口类来供开发人员编写filter程序:Filter,FilterChain,FilterConfig。

Filter程序是一个实现了Filter接口的JAVA类,与servlet程序相似,它由servlet容器进行调用和执行。

Filter程序需要在web.xml文件中进行注册和设置它所能拦截的资源:Filter程序可以拦截Jsp,Servlet,静态图片文件和静态HTML文件。Center

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实例:

新建两个页面,实现跳转:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <a href="two.jsp">to two.jsp</a>
  8. </body>
  9. </html>
  10. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  11. <html>
  12. <head>
  13. <title>Title</title>
  14. </head>
  15. <body>
  16. <h2>TWO</h2>
  17. </body>
  18. </html>

实现filter接口:

  1. package com.sa.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class HelloFilter implements Filter{
  5. @Override
  6. public void init(FilterConfig filterConfig) throws ServletException {
  7. System.out.println("init");
  8. }
  9. @Override
  10. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  11. System.out.println("doFilter");
  12. }
  13. @Override
  14. public void destroy() {
  15. System.out.println("destroy");
  16. }
  17. }

在web.xml中配置filter:

  1. <filter>
  2. <filter-name>helloFilter</filter-name>
  3. <filter-class>com.sa.filter.HelloFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>helloFilter</filter-name>
  7. <url-pattern>/pages/filter/two.jsp</url-pattern>
  8. </filter-mapping>

测试:

Center 1

Center 2

Filter相关API:

Filter接口:

public void init(FilterConfig filterConfig) throws ServletException :类似于servlet的init方法,在创建filter对象后,立即执行,且只执行一次。filter对象在servlet容器加载当前web应用时被创建。该方法用于对当前的filter进行初始化操作,Filter实例是单例的。FilterConfig类似于ServletConfig,可以在web.xml文件中,配置当前filter的初始化参数。

  1. <filter>
  2. <filter-name>helloFilter</filter-name>
  3. <filter-class>com.sa.filter.HelloFilter</filter-class>
  4. <init-param> <param-name>name</param-name> <param-value>sasa</param-value> </init-param>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>helloFilter</filter-name>
  8. <url-pattern>/pages/filter/two.jsp</url-pattern>
  9. </filter-mapping>

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException :真正的filter逻辑代码需要编写在该方法中。每次拦截都会调用该方法。

  1. @Override
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  3. System.out.println("doFilter");
  4. //放行 filterChain.doFilter(servletRequest,servletResponse);
  5. }

FilterChain:Filter链,多个Filter构成一个Filter链。把请求传给Filter链中的下一个Filter,若当前Filter是Filter链的最后一个,将把请求给到目标Servlet或JSP。多个filter拦截的顺序和 配置的顺序有关,靠前的先被调用。

public void destroy():销毁释放当前filter所占用的资源,在filter销毁之前被调用,且只被调用一次。

实现登录拦截:

login.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>登录</title>
  5. </head>
  6. <body>
  7. <h2>${msg}</h2>
  8. <form action="<%=request.getContextPath()%>/pages/filter/hello.jsp" method="post">
  9. name:<input type="text" name="name">
  10. pwd:<input type="text" name="pwd">
  11. <input type="submit" value="提交">
  12. </form>
  13. </body>
  14. </html>

hello.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <h1>hello:{param.name}></h1>
  8. </body>
  9. </html>

NameFilter:

  1. package com.sa.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import java.io.IOException;
  6. public class NameFilter implements Filter{
  7. private FilterConfig filterConfig;
  8. @Override
  9. public void init(FilterConfig filterConfig) throws ServletException {
  10. this.filterConfig=filterConfig;
  11. }
  12. @Override
  13. public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
  14. String name=request.getParameter("name");
  15. String name1=filterConfig.getInitParameter("name");
  16. if (!name.equals(name1)) {
  17. request.setAttribute("msg", "名字错辣");
  18. request.getRequestDispatcher("/pages/filter/login.jsp").forward(request,response);
  19. return;
  20. } else {
  21. filterChain.doFilter(request, response);
  22. }
  23. }
  24. @Override
  25. public void destroy() {
  26. }
  27. }

PwdFilter:

  1. package com.sa.filter;
  2. import javax.servlet.*;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import java.io.IOException;
  6. public class PwdFilter implements Filter{
  7. private FilterConfig filterConfig;
  8. @Override
  9. public void init(FilterConfig filterConfig) throws ServletException {
  10. this.filterConfig=filterConfig;
  11. }
  12. @Override
  13. public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
  14. String pwd=request.getParameter("pwd");
  15. String pwd1=filterConfig.getServletContext().getInitParameter("pwd");
  16. if (!pwd.equals(pwd1)) {
  17. request.setAttribute("msg", "密码错辣");
  18. request.getRequestDispatcher("/pages/filter/login.jsp").forward(request,response);
  19. return;
  20. } else {
  21. filterChain.doFilter(request, response);
  22. }
  23. }
  24. @Override
  25. public void destroy() {
  26. }
  27. }

配置web.xml:

  1. <filter>
  2. <filter-name>nameFilter</filter-name>
  3. <filter-class>com.sa.filter.NameFilter</filter-class>
  4. <init-param>
  5. <param-name>name</param-name>
  6. <param-value>sasa</param-value>
  7. </init-param>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>nameFilter</filter-name>
  11. <url-pattern>/pages/filter/hello.jsp</url-pattern>
  12. </filter-mapping>
  13. <filter>
  14. <filter-name>pwdFilter</filter-name>
  15. <filter-class>com.sa.filter.PwdFilter</filter-class>
  16. </filter>
  17. <filter-mapping>
  18. <filter-name>pwdFilter</filter-name>
  19. <url-pattern>/pages/filter/hello.jsp</url-pattern>
  20. </filter-mapping>
  21. <context-param>
  22. <param-name>pwd</param-name>
  23. <param-value>123</param-value>
  24. </context-param>

测试:

Center 3

Center 4

Center 5

Center 6

Dispatcher元素:指定过滤器所拦截的资源被servlet容器调用的方式,可以是request,include,forword,error之一,默认为request,可以设置多个子元素来指定filter对资源的多种调用方式进行拦截。

①:request:当用户直接访问页面时,web容器将会调用过滤器,如果目标资源是通过requestDispatcher的include()或forWord()方法访问则不会触发过滤器。

通过get或post请求直接访问。

②:forword:如果目标资源是通过requestDispatcher的forword()方法访问时,那么该过滤器将会被调用,除此之外,该过滤器不会被调用。

或通过page指令的errorPage转发页面,<%@page errorPage=”error.jsp”%>

③:include:如果目标资源是通过requestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

④:error:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

在web.xml文件中通过error-page节点声明

测试:

现在想通过两种方式访问two.jsp:一种是通过request请求,一种是通过forword请求。

one.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <script>
  4. function a() {
  5. window.location.href="<%=request.getContextPath()%>/pages/1011/two.jsp";
  6. }
  7. </script>
  8. <head>
  9. <title>one</title>
  10. <button οnclick="a();" >request</button>
  11. </head>
  12. <body>
  13. </body>
  14. </html>

two.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>two</title>
  5. </head>
  6. <body>
  7. <h1>this is two</h1>
  8. </body>
  9. </html>

three.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>three</title>
  5. </head>
  6. <body>
  7. <a href="four.jsp">forword</a>
  8. </body>
  9. </html>

four.jsp:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>four</title>
  5. </head>
  6. <body>
  7. <jsp:forward page="two.jsp"></jsp:forward>
  8. </body>
  9. </html>

filter1:

  1. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
  2. System.out.println("Filter1");
  3. chain.doFilter(req, resp);
  4. }

filter2:

  1. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
  2. System.out.println("Filter2");
  3. chain.doFilter(req, resp);
  4. }

配置xml:

  1. <filter>
  2. <filter-name>Filter1</filter-name>
  3. <filter-class>com.sa.filter.Filter1</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>Filter1</filter-name>
  7. <url-pattern>/pages/1011/two.jsp</url-pattern>
  8. </filter-mapping>
  9. <filter>
  10. <filter-name>Filter2</filter-name>
  11. <filter-class>com.sa.filter.Filter2</filter-class>
  12. </filter>
  13. <filter-mapping>
  14. <filter-name>Filter2</filter-name>
  15. <url-pattern>/pages/1011/two.jsp</url-pattern>
  16. </filter-mapping>

通过request访问two.jsp:

Center 7

通过forword访问two.jsp:

Center 8

可以得知filter的默认监视请求方式是request。

修改xml文件:

  1. <filter>
  2. <filter-name>Filter1</filter-name>
  3. <filter-class>com.sa.filter.Filter1</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>Filter1</filter-name>
  7. <url-pattern>/pages/1011/two.jsp</url-pattern>
  8. </filter-mapping>
  9. <filter>
  10. <filter-name>Filter2</filter-name>
  11. <filter-class>com.sa.filter.Filter2</filter-class>
  12. </filter>
  13. <filter-mapping>
  14. <filter-name>Filter2</filter-name>
  15. <url-pattern>/pages/1011/two.jsp</url-pattern>
  16. <dispatcher>FORWARD</dispatcher>
  17. </filter-mapping>

通过request访问two.jsp:
Center 9
通过forword访问two.jsp:
Center 10

发表评论

表情:
评论列表 (有 0 条评论,413人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Filter 过滤器

    Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作。 1.什么是Filter及其作用介绍      Filter是sun公司中servlet2.3后增加的一

    相关 Filter过滤器

    Filter的基本功能是对servlet容器调用servlet的过程进行拦截,从而在servlet进行响应处理的前后实现一些特殊的功能。 在servletAPI中定义了三个接

    相关 Filter过滤器

    过滤器: 过滤   过滤请求 可以写多个 从用户访问  ->第一个过滤器  -> 第二个过滤 -> servlet   生命周期:随着项目的启动而创建 当访问了地址后而

    相关 Filter过滤器

    一、Filter过滤器 1、介绍       Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态资源文件等进行

    相关 Filter 过滤器

    > 过滤器,其实就是对客户端发出来的请求进行过滤。浏览器发出,然后服务器派Servlet处理。在中间就可以过滤,其实过滤器起到的是拦截的作用,也就是拦截器。 作用