JavaWeb-Filter

发布时间:2024年01月21日
一、概念

Filter:过滤器,JavaWeb三大组件(Servlet,Filter,Listener)之一。作用是把对资源的请求拦截下来,从而实现一些特殊的功能。一般完成一些通用的操作,比如:权限控制、统一编码处理、敏感字符处理等。

二、快速使用

上面提到Filter是JavaWeb的三大组件之一,那么可想而知其使用过程与Servlet开发是极其相似的。即实现固定接口Filter,覆盖相关方法doFilter,注解配置路径@WebFilter三步即可。

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter demo...");
        // 一定要有这一行,表示处理完请求后,放行,会请求到目标资源
        filterChain.doFilter(servletRequest, servletResponse);
        // 请求完目标资源后,将回到此处
        // todo
    }

    @Override
    public void destroy() {

    }
}
三、执行流程

请求会在到达Servlet之前与响应离开Servlet之后进行拦截和过滤处理,而分界点就是上面代码片段中的filterChain.doFilter(req, resp)方法。总结:执行放行前逻辑-放行-访问目标资源-执行放行后逻辑。因此,我们常常在该方法之前对请求参数做处理,在该方法之后对响应做处理。

四、过滤器链

如果有多个过滤器,则会形成一个过滤器链,执行流程如下所示:

如果是注解配置的Filter,优先级会按照名称自然排序

五、登录小案例

在一个系统中,我们不允许未登录状态下去访问一些资源,如果拦截器发现是未登录状态时,则不允许访问目标资源,自动跳转到登录页面。

(1)先准备一个用于登录的页面,需要填写用户名与密码,我们把信息提交到/login的servlet中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tomcat</title>
</head>
<body>
<h1>hello tomcat</h1>

<form action="/javaweb/login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit">

</form>
</body>
</html>

(2)在登录的servlet中,我们完成用户名与密码的验证,并利用session将登录状态设置为已登录,并跳转到hello.jsp页面中

import com.byhuang.mvc.mapper.UserMapper;
import com.byhuang.mvc.util.SqlSessionFactoryUtil;
import com.byhuang.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        HttpSession session = req.getSession();

        String username = (String) req.getParameter("username");
        String password = (String) req.getParameter("password");

        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserByName(username);
        System.out.println(user);
        if (Objects.nonNull(user) && password.equals(user.getPassword())) {
            session.setAttribute("is_login", true);
        }
        req.getRequestDispatcher("/hello.jsp").forward(req, resp);
    }
}

(3)我们在拦截器中设置,要访问hello.jsp页面会被拦截,必须先校验session域中的登录状态,校验不通过则转到登录页面a.html中

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

@WebFilter("/hello.jsp")
public class LoginFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        System.out.println(session.getId());
        Object isLogin = session.getAttribute("is_login");
        if (Objects.isNull(isLogin) || !(boolean) isLogin) {
            httpServletRequest.getRequestDispatcher("/a.html").forward(servletRequest, servletResponse);
        }
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("request back...");
    }

    @Override
    public void destroy() {

    }
}

(4)测试:我们直接访问hello.jsp时,会重定向到a.html页面要求先登录。在登录后,我们可以打开一个新的浏览器tab页,可以直接访问hello.jsp页面。

以上便是我们对Filter的介绍,请读者关注下一篇关于Listener的介绍,届时我们将完成对Java Web三大组件的介绍。

文章来源:https://blog.csdn.net/buzzkiller/article/details/135724456
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。