filter学习

一、过滤器Filter简介

filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理。


编写步骤
1)编写一个过滤器的类实现Filter接口
2)实现接口中尚未实现的方法(着重实现doFilter方法)
3)在web.xml中进行配置(主要是配置要对哪些资源进行过滤)


API详解

Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
1、init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
2、doFilter(ServletRequest,ServletResponse,FilterCha):代表filter执行过滤的核心方法,如果某资源在已经被配置到这个filter进行过滤的话,那么每次访问这个资源都会执行doFilter方法,注意 这里的request和response没有http 需要强制转换。
3、destory():代表是filter销毁方法 当filter对象销毁时执行该方法

Filter的执行顺序由xml文件中mapping的顺序决定。


Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁


filter的过滤过程


filter配置方法 与servlet类似

路径也可以用servlet的名字替代
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转时执行filter

二、总结Filter的作用

1)公共代码的提取
2)可以对request和response中的方法进行增强(装饰者模式/动态代理)
3)进行权限控制


1、自动登陆案例
此时已写好登陆的框架,添加一个自动登陆的复选框。如果登陆成功 则将用户名和密码为客户端写一个cookie,编写一个filter,使得访问所以页面的时候先检测有无cookie,有则尝试登陆。此时filter不是作为筛选,而是作为功能的增强。

web层servlet方法如下

public class ServletLogin extends HttpServlet {


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8"); //解析中文

        //获取 信息
        String username = request.getParameter("username"); 
        String password = request.getParameter("password");
        String autoLoginin = request.getParameter("autoLogin"); //获得是否自动登陆 勾选为on 不勾选为null

        //登陆成功 重定向到首页  失败则转发到本页面显示
        user user = null ;
        try {
            user = new service().Login(username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }


        if(user!=null)  //登陆成功 重定向:如果用转发下次请求即丢失登陆信息 同时改变地址栏信息提示用户
        {

            //判断是否勾选了自动登陆   为客户端写一个cookie 储存用户名和密码
            if(autoLoginin.equals("on"))
            {
                String username_code = URLEncoder.encode(username, "UTF-8");// 如果要往cookie中存入中文信息,先进行编码,获取时再解码

                Cookie cusername = new Cookie("cusername", username_code);
                Cookie cpassword = new Cookie("cpassword", user.getPassword());
                cusername.setMaxAge(60*60);
                cpassword.setMaxAge(60*60);
                cusername.setPath(request.getContextPath());
                cpassword.setPath(request.getContextPath());
                response.addCookie(cusername);
                response.addCookie(cpassword);
            }       


            HttpSession session = request.getSession(); //存入user信息,以便主页显示其用户名
            session.setAttribute("user",user);
            response.sendRedirect(request.getContextPath()+"/index.jsp");           
        }

        //登陆失败 转发到本页面,并且输出信息
        else
        {
            request.setAttribute("loginInfo", "账号或者密码错误");  
            request.getRequestDispatcher("/login.jsp").forward(request, response);

        }   
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        doGet(request, response);
    }
}

filter代码如下

public class AutoLogin implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //自动登陆增强  配置/* 每个资源都先访问这里,如果cookie中有信息则尝试登陆
        HttpServletRequest req=(HttpServletRequest)request;
        Cookie[] cookies = req.getCookies();
        String username = null;
        String password = null;
        if(cookies!=null)
        {
            for(Cookie cookie:cookies)
            {
                if("cusername".equals(cookie.getName()))
                {
                    username=cookie.getValue(); //获取用户名信息,后进行转码
                    username = URLDecoder.decode(username, "UTF-8");
                }

                if("cpassword".equals(cookie.getName()))
                    password=cookie.getValue();
            }
        }

        if(password!=null&&username!=null)
        {
            //尝试登陆
            user user = null ;
            try {
                user = new service().Login(username,password);
            } catch (SQLException e) {
                e.printStackTrace();
            }

            if(user!=null)  //登陆成功 写入session 以便后续网站获取显示
            {
                HttpSession session = req.getSession();
                session.setAttribute("user",user);
            }   
        }

        //无论登陆是否成功  均进行放行
        chain.doFilter(request, response);
    }

    public void destroy() {
    }
    public void init(FilterConfig fConfig) throws ServletException {    
    }
}

servlet中代码句
String username_code = URLEncoder.encode(username, “UTF-8”);
是为了将cookie中写入中文信息,先将中文按utf-8码表编码。而后在filter中代码
username = URLDecoder.decode(username, “UTF-8”);
重新将信息进行解码。


2、修改全局乱码
可以用filter对request进行编码设置,如果方法为post,当然只用简单的一句代码即可解决。当如果提交方法为get,为了每次获取信息都进行编码再解码,编写一个filter使用装饰者模式增强get方法。
其中HttpServletRequestWrapper 为专门用来实现装饰者模式的类,直接覆写其中的方法即可。

public class encoding implements Filter {

    class EnhanceRequest extends HttpServletRequestWrapper {        //专门用来继承的类,可以只覆写其中几个方法 如果用实现接口,则每个方法都实现
        private HttpServletRequest request = null;
        public EnhanceRequest(HttpServletRequest request) {
            super(request);
            this.request=request;
        }

        @Override       //覆写需要的方法
        public String getParameter(String name) {
            String parameter = request.getParameter(name);
            try {
                parameter = new String(parameter.getBytes("ISO8859-1"),"UTF-8");    //重新编码再解码 获得中文
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return parameter;
        }  
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        EnhanceRequest enhanceRequest = new EnhanceRequest((HttpServletRequest) request);
        chain.doFilter(enhanceRequest, response);   //传入增强类,则后面所调用的方法都是该增强类的方法

    }
    public void destroy() {}
    public void init(FilterConfig fConfig) throws ServletException {}
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值