Filter过滤器和案例

Filter总结

简介

Filter中文意思为过滤器。顾名思义,过滤器可在浏览器以及目标资源之间起到一个过滤的作用,是JavaWeb的三大web组件之一:Servlet、Filter、Listener。当服务器收到特定的请求后,会先将请求交给过滤器,程序员可以在过滤器中对请求信息进行读取修改等操作,然后将请求信息再发送给目标资源。目标资源作出响应后,服务器会再次将响应转交给过滤器,在过滤器中同样可以对响应信息做一些操作,然后再将响应发送给服务器。在一个WEB应用中可以部署多个过滤器,多个过滤器就组成了一个过滤器链,请求和响应必须在经过多个过滤器后才能到达目标。

Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:在客户端的请求访问后端资源之前,拦截这些请求;在服务器的响应发送回客户端之前,处理这些响应。过滤器的使用场景有:身份验证过滤器;敏感词汇过滤;数据压缩过滤;加密过滤;触发资源访问事件过滤;图像转换过滤;日志记录和审核过滤;MIME-TYPE 链过滤;标记化过滤;XSL/T 过滤

Filter使用

右键–>new–>Filter,结构如下

@WebFilter(filterName = "Filter")
public class Filter implements javax.servlet.Filter {
    public void destroy() {  //销毁
    }
    //该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {  //初始化
    }
}

注解配置Filter

使用value或者urlPatterns配置Filter的拦截资源:
1)拦截具体资源路径:/index.jsp
2)拦截目录:/user/*
3)后缀名拦截:*.jsp 访问后缀名为jsp的资源时过滤器被执行
4)拦截所有资源:/ * (没有空格)

urlPatterns = "/*"

initParams:配置初始化参数

initParams = {
        @WebInitParam(name = "key",value = "value")
}

dispatcherTypes:配置拦截的类型,可配置多个,默认为DispatcherType.REQUEST,表示拦截直接请求的资源,DispatcherType.FORWARD表示拦截转发请求的资源,若要直接请求和转发请求的资源都拦截则把两个属性都写进来。

dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD}

web.xml配置Filter

<filter>
        <filter-name>Filter</filter-name>
        <filter-class>demo.Filter</filter-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>tom</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Filter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

Filter链

多个Filter组成Filter链,在注解中的执行顺序为比较类名字符串大小,小的先执行,在web.xml中按照filter-mapping的先后顺序执行。

Filter案例

验证登录

验证是否登录,如果登录了,直接放行,如果没有登录,则跳转到登录页面,提示用户登录。

package demo;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName = "Filter",urlPatterns = "/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
public class Filter implements javax.servlet.Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //强转
        HttpServletRequest request = (HttpServletRequest) req;
        //获取资源请求路径
        String requestURI = request.getRequestURI();
        //判断是否包含登录相关资源路径,要注意排除掉css/js/图片/验证码等资源
        if (requestURI.contains("/login.jsp") || requestURI.contains("/loginServlet") || requestURI.contains("/css/") || requestURI.contains("/js/") || requestURI.contains("/fonts/") || requestURI.contains("/checkCodeServlet")) {
            chain.doFilter(req, resp);
        }else {
            Object user = request.getSession().getAttribute("user");
            if (user != null) {
                chain.doFilter(req,resp);
            }else {
                request.setAttribute("login_msg","您尚未登录,请登录");
                request.getRequestDispatcher("/login.jsp").forward(request,resp);
            }
        }
//        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {
    }
}

过滤敏感词汇

对录入的词汇进行敏感词过滤,敏感词汇参考《敏感词汇.txt》,如果是敏感词汇,替换为****。
分析: 要使用动态代理对request对象进行增强。

package sensitivewords;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**
 * 敏感词汇过滤器
 */
@WebFilter(filterName = "SensitiveWordsFilter",urlPatterns = "/*",dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.FORWARD})
public class SensitiveWordsFilter implements javax.servlet.Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //创建代理对象,增强getParameter方法
        ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //增强getParameter方法
                //判断是否是getParameter方法
                if (method.equals("getParameter")) {
                    //增强返回值
                    //获取返回值
                    String value = (String) method.invoke(req,args);
                    if (value != null) {
                        for (String str : list) {
                            if (value.contains(str)) {
                                value = value.replaceAll(str,"****");
                            }
                        }
                    }
                    return value;
                }
                return method.invoke(req,args);
            }
        });

        chain.doFilter(proxy_req, resp);
    }

    private List<String> list = new ArrayList<>();
    public void init(FilterConfig config) throws ServletException {
        try {
            //加载文件
            ServletContext servletContext = config.getServletContext();
            String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
            //读取文件
//            BufferedReader br = new BufferedReader(new FileReader(realPath));
            InputStreamReader isr = new InputStreamReader(new FileInputStream(realPath),"UTF-8");
            BufferedReader br = new BufferedReader(isr);
            //将文件的每一行数据添加到list中
            String line = null;
            while ((line = br.readLine()) != null) {
                list.add(line);
            }
            br.close();
            System.out.println(list);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

测试servlet:

package sensitivewords;
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;
@WebServlet(urlPatterns = "/testServlet")
public class TestServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        response.setCharacterEncoding("UTF-8");
//        response.setContentType("text/html;charset=UTF-8");
        String name = request.getParameter("name");
        String msg = request.getParameter("msg");
        System.out.println(name+":"+msg);
        response.getWriter().write(name+":"+msg);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值