过滤器浅谈

过滤器

过滤器是什么,为什么需要用过滤器

过滤器就是它的字面意思,它能够对任何非法请求进行拦截。举个例子来说,就是你去银行取钱不能够不登录账号就直接进入到取钱页面,这是为什么呢?原因是你直接访问取钱页面的请求被过滤器拦截了。
有人可能就问了,不就是个判断吗,直接在取钱页面直接加上就好了,效果是一样的。不可否认,说的很对,但是,如果我要是有100个不同的页面请求呢,咬咬牙也能加,要是有1万个呢,过滤器的创建方便以外,其实你想想每个页面都加,会增加多少代码量呢?为了减轻负担,活用我们四大特性之一抽象,我们就把它给取出来,也不用每个页面调用才能实现,会自动拦截,不符合要求的请求。

过滤器介绍

我们过滤器主要是采用继承(extend)Filter接口(Filter interface)来实现,既然是个接口就要重写方法,接下来就介绍下它的方法:

  1. init(FilterConfig filter Config)初始化方法,一般在服务器启动的时候就执行了,但是本人不才,能够详细了解到它的深层,我就给大家说一下我的发现吧,init方法中初始化是存在顺序的,且那个顺序一不是通过首字母顺序,二不是通过创建时间,三它的顺序是固定的,不是重写部署就出现一个版本的顺序,笔者认为是系统内部设置了顺序,但是平时可能不常见。
  2. doFilter(ServletRequest request,ServletResponse response, FilterChain chain)这个叫做过滤器拦截的业务逻辑处理,主要就是存放一些放行判断的,就好比我把登录界面拦了下来,但是你不登陆我就不能让你通行,就陷入了逻辑闭环,先有鸡还是先有蛋呢,因此我们要在这里进行放行。放行的时候我们使用的是它后面那个参数chain,这东西结合chain.doFilter(request,response)就能够执行放行操作(访问servlet),但是 chain这个东西是链的意思,所以聪明的你已经看出来了,过滤器之间是如何避免你拦下我,我拦下你的冰雪蜜城行为了,对,doFilter也存在一个顺序,那么它的顺序也和init一样让人捉摸不定吗?肯定不能,要不然每次还要猜测顺序,很麻烦,它的顺序是你创建Filter这个类文件文件名的首字母的顺序进行的。
  3. destroy()有了创建有了应用,就肯定要有释放,要不然大家用完就扔在哪里,弱小无助的浏览器会吃不消的

实战演示

说了很多的话,不如来一遍实践。事实胜于雄辩
EncodingFilter.java 这个是用来将post请求的编码格式变成utf-8


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(filterName = "encoding", urlPatterns = "/*")
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("EncodingFilter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("EncodingFilter.doFilter");
        // servletRequest.setCharacterEncoding("utf-8"); 此行代码不能生效,需要使用HttpServletRequest进行编码
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod(); // 获取是get还是post
        // 如果是post请求,我们就处理乱码问题
        if (method.equalsIgnoreCase("post")){
            httpServletRequest.setCharacterEncoding("UTF-8");
        }
        // 如果是post请求,解决乱码问题之后,继续往后执行,否则直接往下执行
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("EncodingFilter.destroy");
    }
}

LoginFilter


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
// /*表示能够将全部请求拦下来,进行筛选
@WebFilter(filterName = "Login", urlPatterns = "/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LoginFilter.init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("LoginFilter.doFilter");
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        HttpSession session = httpServletRequest.getSession();



        // 仅放行登录(如果还有用户的增删改查之类操作的话)
        // 如果不放行登录,那么就会陷入死循环,登录被拦截,然后重定向到登录,然后在被拦截,进入循环
        String method = httpServletRequest.getParameter("method");
        String servletPath = httpServletRequest.getServletPath();
        if (servletPath.equals("/login.jsp")	// 这里放行登录页面,这是直接访问登录页面的形式
                || servletPath.equals("/user") && (method.equals("login"))	// 这里放行登录页面(这是调用方法的形式)
                || servletPath.equals("/fail.html") // 这里放行登录错误页面
                || servletPath.endsWith(".js")	// 这里放行前端的一些jQuery之类的
                || servletPath.endsWith(".css")	// 这里放行bootStrap之类的
                || servletPath.equals("/code")) { // 这里放行的是生成验证码的
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        // 通过session里面存的数据,查看有没有一个叫做user的对象,如果有就是找到了,即登陆成功,只有登陆成功才能创建出一个user对象
        User user = (User) session.getAttribute("user");
        if (user == null) {
            httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/login.jsp");
            return;
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("LoginFilter.destroy");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值