kkFileView代码分析(十)——过滤器分析
发布日期:2022-03-08 21:50:39 浏览次数:4 分类:技术文章

本文共 6308 字,大约阅读时间需要 21 分钟。

2021SC@SDUSC

        接下来我们开始对filter文件夹进行分析,Filter我在很多web项目中都有看到,但是一直都不太明白filter的工作,所以借这个项目来探索一下filter。

目录


Filter分析

简介:

        Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等特殊的功能。

作用:

        它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。

        使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。        在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。        在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

图源:博客园 

调用方式

        开发filter时要先编写java类实现Filter接口,并实现其doFilter方法;之后在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。

         Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,Web服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

  1. 调用目标资源之前,让一段代码执行。
  2. 判断是否调用目标资源,即是否让用户访问web资源。

        web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法, 开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

        在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter。当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

生命周期

        Filter的创建和销毁由web服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。

项目中的Filter分析

该项目中有关filter的文件有如下几个:

1、AttributeSetFilter分析

        在类里重写了doFilter方法,是filter中拦截请求的操作实现,完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候,Servlet过滤器将先执行doFilter方法。FilterChain参数用于访问后续过滤器。

@Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {        this.setWatermarkAttribute(request);        this.setFileAttribute(request);        filterChain.doFilter(request, response);    }

         这个类主要检测两中request:

                办公文件预览是否已具备相关需要属性;

                水印的属性设置。

private void setFileAttribute(ServletRequest request){        HttpServletRequest httpRequest = (HttpServletRequest)request;        request.setAttribute("pdfDownloadDisable", ConfigConstants.getPdfDownloadDisable());        request.setAttribute("fileKey", httpRequest.getParameter("fileKey"));        request.setAttribute("switchDisabled", ConfigConstants.getOfficePreviewSwitchDisabled());        request.setAttribute("fileUploadDisable", ConfigConstants.getFileUploadDisable());    }    private void setWatermarkAttribute(ServletRequest request) {        String watermarkTxt = request.getParameter("watermarkTxt");        request.setAttribute("watermarkTxt", watermarkTxt != null ? watermarkTxt : WatermarkConfigConstants.getWatermarkTxt());        request.setAttribute("watermarkXSpace", WatermarkConfigConstants.getWatermarkXSpace());        request.setAttribute("watermarkYSpace", WatermarkConfigConstants.getWatermarkYSpace());        request.setAttribute("watermarkFont", WatermarkConfigConstants.getWatermarkFont());        request.setAttribute("watermarkFontsize", WatermarkConfigConstants.getWatermarkFontsize());        request.setAttribute("watermarkColor", WatermarkConfigConstants.getWatermarkColor());        request.setAttribute("watermarkAlpha", WatermarkConfigConstants.getWatermarkAlpha());        request.setAttribute("watermarkWidth", WatermarkConfigConstants.getWatermarkWidth());        request.setAttribute("watermarkHeight", WatermarkConfigConstants.getWatermarkHeight());        request.setAttribute("watermarkAngle", WatermarkConfigConstants.getWatermarkAngle());    }

2、BaseUrlFilter分析

        url过滤器,对url进行判断是否符合需要。

@Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {        String baseUrl;        StringBuilder pathBuilder = new StringBuilder();        pathBuilder.append(request.getScheme()).append("://").append(request.getServerName()).append(":")                .append(request.getServerPort()).append(((HttpServletRequest) request).getContextPath()).append("/");        String baseUrlTmp = ConfigConstants.getBaseUrl();        if (baseUrlTmp != null && !ConfigConstants.DEFAULT_BASE_URL.equalsIgnoreCase(baseUrlTmp)) {            if (!baseUrlTmp.endsWith("/")) {                baseUrlTmp = baseUrlTmp.concat("/");            }            baseUrl = baseUrlTmp;        } else {            baseUrl = pathBuilder.toString();        }        BASE_URL = baseUrl;        request.setAttribute("baseUrl", baseUrl);        filterChain.doFilter(request, response);    }

3、ChinesePathFilter

        中文路径过滤器,将字符集编码都设置为UTF-8,防止分析路径时出现乱码等问题。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        request.setCharacterEncoding("UTF-8");        response.setCharacterEncoding("UTF-8");        chain.doFilter(request, response);    }

4、TrustHostFilter

        判断url的来源是否可信任的来源,以保护用户信息安全。

@Override    public void init(FilterConfig filterConfig) {        ClassPathResource classPathResource = new ClassPathResource("web/notTrustHost.html");        try {            classPathResource.getInputStream();            byte[] bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());            this.notTrustHost = new String(bytes, StandardCharsets.UTF_8);        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {        String url = getSourceUrl(request);        if(url != null){            url = new String(Base64Utils.decodeFromString(url), StandardCharsets.UTF_8);        }        String host = getHost(url);        if (host != null &&!ConfigConstants.getTrustHostSet().isEmpty() && !ConfigConstants.getTrustHostSet().contains(host)) {            String html = this.notTrustHost.replace("${current_host}", host);            response.getWriter().write(html);            response.getWriter().close();        }        chain.doFilter(request, response);    }    private String getHost(String urlStr) {        try {            URL url = new URL(urlStr);            return url.getHost().toLowerCase();        } catch (MalformedURLException ignored) {        }        return null;    }

转载地址:https://blog.csdn.net/m0_55503427/article/details/121956553 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:蓝桥杯2013年第四届真题-打印十字图(python)
下一篇:kkFileView代码分析(七)——FileUtils

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月19日 19时38分46秒