5. 过滤器

今天内容:
1.Servlet最激动人心三大技术:Servlet,Filter,Listener

2.过滤器(Filter):Servlet三大技术之一,在服务器可以管理所有web资源,本质特殊java类.
WEB开发人员通过Filter技术,对web服务器管理 的所有web资源:例如Jsp, Servlet, 静态图片文件或静态html文件等进行拦截,从而实现一些特殊 的功能。
过滤器的作用:实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

3.过滤器工作原理:
在这里插入图片描述

4.手动写过滤类:

	4.1:先创建一个Java类,实现javax.servlet.Filter接口;
	4.2:实现接口中init(),doFilter(),destroy();
	4.3:在web.xml中注册过滤器
		注意:配置版的过滤器在过滤器链中顺序由注册顺序.
		eg:<!--注册过滤器-->
<filter>
    <filter-name>FirstFilter</filter-name><!--过滤器注册名-->
    <filter-class>com.qf.day46.filter.FirstFilter</filter-class><!--过滤器全限制类名:包名+类名-->
</filter>
<!--配置过滤过滤请求的路径-->
<filter-mapping>
    <filter-name>FirstFilter</filter-name><!--过滤器的注册名,与上面注册名相同-->
    <url-pattern>/*</url-pattern><!--过滤所有请求-->
</filter-mapping>

//等同于用注解在类名上注册
	@WebFilter(filterName = "SecondFilter",value = "/*")//配置注册信息和映射请求
简写为:@WebFilter("/*")
注意:注解版的过滤器在过滤器链中顺序由注册过滤器名称决定.

5.过滤器的生命周期:

     当项目发布时,由服务器容器调用构造方法,实例化过滤器,再由服务器容器通
过过滤 实例调用init()初始过滤器,当客户端发送请求到服务器时,由服务器容器通
过过滤 器实例调用doFilter方法,再将请求传到Servlet中处理,Servlet处理完请
求响应 信息,由服务器容器通过过滤器实例调用doFilter方法,再将响应信息传到客
户端. 当web项目停止发布时就调由服务器容器通过过滤器实例调用destroy()销毁
过滤器 实例.(与web项目同生共死)

6.Servlet3.0之后,注解的过滤器:在过滤类上面配置注解@WebFilter,可配置属性
在这里插入图片描述

7.字符编码过滤器:

	原来实现:  请求和响应对象是在Servlet中处理编码
	现在实现:  在过滤器中处理编码,将处理好编码的请求和响应对象传Servlet中,Servlet就	不会再处理编码 
	实现思路:  声明一个字符编码过滤器,在过滤器中将响应的编码和请求编码提前编码后,后	面在将请求和响应对象传Servlet中就不用处理编码.注意,因为get请求的编码无法统一在类中设置,所以就想重写获得请求中数据的方法.因为要重写获得请求中数据的方法,所以请求对象要用装饰都模式.
	eg:/**
 * 字符编码过滤器
 */
@WebFilter("/*")
public class EncoddingFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {

    }
    public void destroy() {
    }

    /**
     * 过滤方法
     * @param request
     * @param response
     * @param chain
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        //统一处理响应编码
        response.setCharacterEncoding("utf-8");
        /*处理请求编码*/
        //将请求对象转换为HttpServletRequest
        HttpServletRequest request2=(HttpServletRequest)request;
        //获得请求方法类型
        if ("GET".equalsIgnoreCase(request2.getMethod())){
            //创建请求的装饰者对象,将原来的请求对象作为构造方法的参数
            MyRequest mr=new MyRequest(request2);
            chain.doFilter(mr, response);
        }else if("POST".equals(request2.getMethod())){//post请求
            request2.setCharacterEncoding("utf-8");
            chain.doFilter(request2, response);
        }
    }

    /**
     * 装饰者请求类(成员内部类)
     */
    public class MyRequest extends HttpServletRequestWrapper{
        public HttpServletRequest request;

        public MyRequest(HttpServletRequest request) {
            super(request);
            this.request=request;
        }

        /**
         * 重写获得单个请求值的方法
         * @param name
         * @return String
         */
        @Override
        public String getParameter(String name) {
            //获得请求中值
            String value=super.getParameter(name);
            try {
                if(value!=null&&!value.equals("")){
                    //重写编码
                    value=new String(value.getBytes("ISO-8859-1"),"utf-8");

                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return value;
        }

        /**
         * 重写获得请求中一组数据值的方法
         * @param name
         * @return String
         */
        @Override
        public String[] getParameterValues(String name) {
            //获得请求中一组数据值
            String[] values=super.getParameterValues(name);
            //将数据值一一编码
            if (values!=null||values.length!=0){
                for (int i=0;i<values.length;i++){
                    try {
                        values[i]=new String(values[i].getBytes("ISO-8859-1"),"utf-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            }
            return values;
        }

        /**
         * 重写获得请求中所有值的方法
         * @return String
         */
        @Override
        public Map<String, String[]> getParameterMap() {
            Map<String,String[]> hmap1=super.getParameterMap();
            //处理请求中每个数据的编码
            for (String key:hmap1.keySet()){
                //通过key得到value值
                String[] values=hmap1.get(key);
                //将数据值一一编码
                if (values!=null||values.length!=0){
                    for (int i=0;i<values.length;i++){
                        try {
                            values[i]=new String(values[i].getBytes("ISO-8859-1"),"utf-8");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return hmap1;
        }
    }

}

8.权限验证过滤器

	原来效果:无论用户是否登录都可以直接访问首页,或其他页面.
	实现效果:只有登录过的用户才能访问首页和其他页面,没有登录过的用户,如果直接访问首页或其他页面,让其3秒跳转到登录页并提示你还没有登录,无法作其他操作.
	实现原理:因为每次请求时都要先经过过滤器再经过Servlet,所以就想一个权限验证过滤器,在这个过滤器中作判断,判断只有登录过的用户才放行调用 
			chain.doFilter	(mr, response);,否则让用户跳转到登录页面.
就超市系统来说:只有登录的页面,登录的请求方法,已经登录过的用户,css,js,img放行
	eg:/**
 * 权限验证过滤器
 */
@WebFilter("/*")
public class AccessFilter implements Filter {
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //将请求和响应对象转换为子类对象
        HttpServletRequest request=(HttpServletRequest) req;
        HttpServletResponse response=(HttpServletResponse)resp;
        //获得session登录的用户信息
        Object ob=request.getSession().getAttribute("u");
        //获得请求的uri
        String uri=request.getRequestURI();
        //获得请求的方法名
        String method=request.getParameter("method");

        //如果是默认起始页,/web_market/login.jsp,登录请求,已经登录过的用户也要放行
        if("/web_market/".equals(uri)||"/web_market/login.jsp".equals(uri)||"login".equals(method)||ob!=null){
            //放行,继续执行请求
            chain.doFilter(request, response);
        }else{//没登录,无法处理后面的请求,就要三秒跳转到登录页面
            //设置响应的内容类型
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("你还没有登录,无法进行其他操作,3秒后跳转到登录页面");
            response.setHeader("refresh","3;url=login.jsp");
        }
    }

    public void init(FilterConfig config) throws ServletException {

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值