JAVA Web过滤器学习

定义:过滤器是一个服务端的软件,它可以截取用户端的请求与响应信息,并对这些信息进行过滤。

工作原理:用户发送请求——>过滤器将用户请求发送至web资源——>资源响应发送至过滤器——>过滤器将web资源的响应发送给用户

过滤器的生命周期
1. 实例化配
置Web.xml,启动时自动加载,只会实例化一次
2. 初始化
执行init()方法,也只执行一次
3. 过滤
doFilter(),执行N次,每次请求都会执行过滤方法
4. 销毁
destroy(),web容器关闭的时候执行

intit():
过滤器的初始化方法,web容器创建过滤器实例后调用这个方法,可以读取web.xml文件中过滤器的参数;
doFilter():
这个方法完成实际的过滤操作,当用户请求访问与过滤器关联的url时,web容器将先调用doFilter方法,FilterChain参数可以调用chain.doFilter,将请求传给下一个过滤器,或利用转发或重定向转发到其他资源。
destory():
web容器在销毁过滤器前调用,释放过滤器占用的资源(多数情况用不到)

问题?
1. 过滤器能否改变用户请求的Web资源,也就是能否改变用户请求的路径? 可以
2. 过滤器能否直接返回数据,能不能直接处理用户请求? 不可以
3. 多个过滤器如何实现?
4. 多个过滤器对应同一个用户路径的执行顺序如何?
过滤器链,按照web.xml中过滤器定义的先后顺序组装成一条链。
web.xml文件配置
这里写图片描述
过滤器的分类
1. request 用户直接访问页面时
2. forward .getRequestDispatcher().forward时调用
3. include .getRequestDispatcher().include时调用
4. error 通过声明式异常处理机制调用时,调用

默认request级别
通常转发更快一些,性能更好一些

  1. ASYNC 支持异步处理(servlet3.0)
    @webfilter注解,将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。
    @webfilter(servletNames=”…”,filterName=”…”)
    @webFilter常用属性
    这里写图片描述
    过滤器在实际项目中的应用场景
  2. 对用户请求进行统一认证
  3. 编码转换
  4. 对用户发送的数据进行过滤替换
  5. 转换图像格式
  6. 对响应的内容进行压缩

登陆案例代码片段

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登陆案例</title>
</head>
<body>
    <form action="servlet/LoginServlet"
        method="post">
        用户名: <input type="text" name="username"> 密码: <input
            type="password" name="password"> <input type="submit"
            value="提交">
    </form>
</body>
</html>
public class LoginServlet extends HttpServlet
{
    /**
     * 
     */
    private static final long serialVersionUID = 8756299071983197411L;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String pwd = req.getParameter("password");

        System.out.println(username);

        if ("admin".equals(username) && "11111".equals(pwd)) {
            //校验通过
            HttpSession session = req.getSession();
            session.setAttribute("username", username);
            resp.sendRedirect(req.getContextPath() + "/success.html");
        }
        else {
            //校验失败
            resp.sendRedirect(req.getContextPath() + "/fail.html");
        }
    }

}
public class LoginFilter implements Filter
{
    private FilterConfig config;

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) arg0;
        HttpServletResponse response = (HttpServletResponse) arg1;
        HttpSession session = request.getSession();

        String nologinPaths = config.getInitParameter("nologinfilter");

        request.setCharacterEncoding(config.getInitParameter("encoding"));//设置字符集

        if (nologinPaths != null) {
            String[] paths = nologinPaths.split(";");
            for (int i = 0; i < paths.length; i++) {
                if (paths[i] == null || "".equals(paths[i])) {
                    continue;
                }
                if (request.getRequestURI().indexOf(paths[i]) != -1) {
                    arg2.doFilter(arg0, arg1);
                    return;
                }
            }

        }

        //登陆页面不可能存在session,直接放行
        if (request.getRequestURI().indexOf("login.html") != -1) {
            arg2.doFilter(arg0, arg1);
            return;//不 return的话,还是会继续往下执行,报错:Cannot call sendRedirect() after the response has been committed
        }
        if (session.getAttribute("username") == null || "".equals(session.getAttribute("username"))) {
            response.sendRedirect("login.html");
        }
        else {
            arg2.doFilter(arg0, arg1);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        config = arg0;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值