本文共 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方法,因此,在该方法内编写代码可达到如下目的:
- 调用目标资源之前,让一段代码执行。
- 判断是否调用目标资源,即是否让用户访问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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!