servlet高级-Filter过滤器

servlet高级-Filter过滤器

可以对调用servlet容器的过程进行拦截,用于在servlet进行响应前后进行实现一些特殊功能。

实例

servlet程序

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 java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/servlet")
public class servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("this is servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("this is servlet");
    }
}

filter程序

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class filter implements Filter{
//    初始化时被调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        PrintWriter out = servletResponse.getWriter();
        out.println("this is filter");
    }
//    销毁时调用
    @Override
    public void destroy() {

    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>filter</title>
  </head>
  <body>
  <jsp:forward page="servlet" />
  </body>
</html>

最后在web.xml文件中配置filter拦截的servlet容器,还可以使用通配符拦截用户请求的所有资源。

<filter>        
    <filter-name>filter</filter-name>        
    <filter-class>filter</filter-class>    
</filter>    
<filter-mapping>        
    <filter-name>filter</filter-name>        
    <url-pattern>/servlet</url-pattern>
</filter-mapping>

运行之后在首页显示的是this is servlet,这种情况下好像并没有拦截请求。直接访问servlet时显示的时this is filter完成了拦截。因为使用forward()方式访问,而web.xml中并没有配置filter拦截的servlet资源被调用的方式。

拦截不同方式的请求

那么如何让filter拦截forward()方式的资源请求呢?

在filter-mapping元素中有一个特殊的子元素dispatcher,指定被拦截servlet资源的请求方式。修改web.xml的配置

<filter>        
    <filter-name>filter</filter-name>        
    <filter-class>filter</filter-class>    
</filter>    
<filter-mapping>        
    <filter-name>filter</filter-name>        
    <url-pattern>/servlet</url-pattern>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

再次访问index.jsp,可以看到显示的是this is filter,成功拦截了forward()方式的资源请求。

dispatcher元素的值有四个

  1. REQUEST :Request.Dispathcer.include()和Request.Dispathcer.forward()方法调用将不会使用过滤器

  2. INCLUDE:Request.Dispathcer.include()方法调用

  3. FORWARD:Request.Dispathcer.forward()方法调用

  4. ERROR:声明异常处理机制调用

Filter链

当多个Filter链对同一个url进行请求过滤时,这些Filter就组成了一个过滤器链。

67789bb76450

 

在上面的实例增加一个filter2程序

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class filter2 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        PrintWriter out = servletResponse.getWriter();
        out.println("before<br>");
        filterChain.doFilter(servletRequest, servletResponse);
        out.println("after<br>");
    }

    @Override
    public void destroy() {

    }
}

修改filter程序

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;

public class filter implements Filter{
//    初始化时被调用
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        PrintWriter out = servletResponse.getWriter();
        out.println("this is filter<br>");
        filterChain.doFilter(servletRequest, servletResponse);
    }
//    销毁时调用
    @Override
    public void destroy() {

    }
}

配置web.xml

<filter>            
    <filter-name>filter</filter-name>            
    <filter-class>filter</filter-class>     
</filter>
<filter>        
    <filter-name>filter2</filter-name>        
    <filter-class>filter2</filter-class>
</filter>
<filter-mapping>        
    <filter-name>filter</filter-name>        
    <url-pattern>/servlet</url-pattern>        
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>     
    <filter-name>filter2</filter-name>        
    <url-pattern>/servlet</url-pattern>        
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

在web.xml中,filte的filter-mapping声明在filter2前面,因此在filter链当中filter首先被调用。用户的请求首先被filter拦截,再被filter2拦截。

程序的执行结果如下

a0b7a544a963

首先调用了filter,然后调用filter2输出before,filter2再放行请求,调用了filter2上层的servlet容器,最后filter2输出了after。

FilterConfig接口

用于获取Filter程序在web.xml中的配置信息

声明 描述
String getFilterName() 返回web.xml中设置的filter-name
String getInitParameter(String name) 返回web.xml中设置的某个初始化参数
Enumeration getInitParameterNames() 返回web.xml中设置的所有初始化参数名称的集合
ServletContext getServletContext () 返回FilterConfig对象中封装的ServletContext对象
------本页内容已结束,喜欢请分享------

文章作者
能不能吃完饭再说
隐私政策
PrivacyPolicy
用户协议
UseGenerator
许可协议
NC-SA 4.0


© 版权声明
THE END
喜欢就支持一下吧
点赞27赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片