Rails源代码分析(8):ActionController::Filter(2)

SpringBoot+Vue+Mysql社区医院信息平台(源码+文档) SpringBoot+Vue+Mysql学生宿舍信息管理系统 WEB端软件项目(源码+文档) 项目包含:①完整源码(后端+管理后台+用户前台);②数据库脚本文件;③万字论文文档;④开题报告;⑤答辩PPT;⑥项目运行视频教程。 项目架构: B/S 架构、MVC 分层设计 技术栈: Java、MySQL、SpringBoot、MyBatis-Plus、Token 权限校验、管理后台 Vue+ElementUI+ECharts、用户前台 Layui+jQuery、Maven 构建。 一、角色设计 学生用户: 注册登录、浏览宿舍信息、查询宿舍安排、在线报修、缴费查询、失物招领、桶装水预订、评论交流、收藏等。 商家用户: 注册登录、桶装水品牌与商品信息维护、预订订单查看与处理。 维修人员: 注册登录、查看待处理报修、接单维修、填写报修处理结果与进度反馈。 管理员: 学生管理、班级管理、宿舍信息管理、宿舍安排管理、报修处理管理、缴费信息管理、卫生检查与文明宿舍管理、失物招领管理、桶装水与商家管理、维修人员管理、公告资讯与轮播图管理等。 二、前台功能模块(学生端) 1. 首页展示:轮播图、宿舍公告、最新动态推荐、常用服务快速入口 2. 宿舍信息模块:宿舍列表、楼栋与房间条件筛选、宿舍详情查看、我的宿舍安排查询 3. 在线报修模块:在线提交宿舍设施报修申请、上传故障描述、查看报修进度与维修处理结果 4. 缴费模块:水电等缴费记录查询、缴费状态查看 5. 卫生检查与文明宿舍:宿舍卫生检查结果公示、文明宿舍展示 6. 失物招领模块:失物信息发布、招领信息发布、详情查看、评论互动 7. 桶装水预订:桶装水品牌与商品浏览、在线预订、我的预订记录查询 8. 假期留宿:假期留校申请提交、申请记录查询 9. 评论与收藏:信息评论、查看他人评论、评论回复互动、收藏感兴趣的内容 10. 个人中心... 立即下载

1 概述 

   昨天主要看了如何使用Filter,今天看看Filter的实现。

   这个Module实现中包含这几块:

  • 1 FilterChain 提供了管理Filter对象的方法
  • 2 Filter 所有Filter基类
  • 3 AroundFilter  继承自  Filter
  • 4 BeforeFilter  继承自  Filter
  • 5 AfterFilter  继承自  Filter

2 代码分析

2.1 FilterChain

  1. class FilterChain < ActiveSupport::Callbacks::CallbackChain #:nodoc:
  2.       #根据filter_type来添加一个filter到chain末尾
  3.       def append_filter_to_chain(filters, filter_type, &block)
  4.         pos = find_filter_append_position(filters, filter_type)
  5.         update_filter_chain(filters, filter_type, pos, &block)
  6.       end
  7.       #根据filter_type来添加一个filter到chain前面
  8.       def prepend_filter_to_chain(filters, filter_type, &block)
  9.         pos = find_filter_prepend_position(filters, filter_type)
  10.         update_filter_chain(filters, filter_type, pos, &block)
  11.       end
  12.       # 创建一个filter
  13.       def create_filters(filters, filter_type, &block)
  14.         filters, conditions = extract_options(filters, &block)
  15.         filters.map! { |filter| find_or_create_filter(filter, filter_type, conditions) }
  16.         filters
  17.       end
  18.       # 忽略一个filter
  19.       def skip_filter_in_chain(*filters, &test)
  20.         filters, conditions = extract_options(filters)
  21.         filters.each do |filter|
  22.           if callback = find(filter) then delete(callback) end
  23.         end if conditions.empty?
  24.         update_filter_in_chain(filters, :skip => conditions, &test)
  25.       end
  26.       private
  27.         # 插入一个filter具体方法
  28.         def update_filter_chain(filters, filter_type, pos, &block)
  29.           new_filters = create_filters(filters, filter_type, &block)
  30.           insert(pos, new_filters).flatten!
  31.         end
  32.         # 查找filter append的位置
  33.         def find_filter_append_position(filters, filter_type)
  34.           # appending an after filter puts it at the end of the call chain
  35.           # before and around filters go before the first after filter in the chain
  36.           unless filter_type == :after
  37.             each_with_index do |f,i|
  38.               return i if f.after?
  39.             end
  40.           end
  41.           return -1
  42.         end
  43.         # 查找filter prepend的位置
  44.         def find_filter_prepend_position(filters, filter_type)
  45.           # prepending a before or around filter puts it at the front of the call chain
  46.           # after filters go before the first after filter in the chain
  47.           if filter_type == :after
  48.             each_with_index do |f,i|
  49.               return i if f.after?
  50.             end
  51.             return -1
  52.           end
  53.           return 0
  54.         end
  55.         # 创建或者查找filter
  56.         def find_or_create_filter(filter, filter_type, options = {})
  57.           update_filter_in_chain([filter], options)
  58.           if found_filter = find(filter) { |f| f.type == filter_type }
  59.             found_filter
  60.           else
  61.             # 如果没有找到,那么根据filter方法来判断类别
  62.             filter_kind = case
  63.             when filter.respond_to?(:before) && filter_type == :before
  64.               :before
  65.             when filter.respond_to?(:after) && filter_type == :after
  66.               :after
  67.             else
  68.               :filter
  69.             end
  70.             # 根据filter类别来创建Filter
  71.             case filter_type
  72.             when :before
  73.               BeforeFilter.new(filter_kind, filter, options)
  74.             when :after
  75.               AfterFilter.new(filter_kind, filter, options)
  76.             else
  77.               AroundFilter.new(filter_kind, filter, options)
  78.             end
  79.           end
  80.         end
  81.         # 更新filter
  82.         def update_filter_in_chain(filters, options, &test)
  83.           filters.map! { |f| block_given? ? find(f, &test) : find(f) }
  84.           filters.compact!
  85.           map! do |filter|
  86.             if filters.include?(filter)
  87.               new_filter = filter.dup
  88.               new_filter.options.merge!(options)
  89.               new_filter
  90.             else
  91.               filter
  92.             end
  93.           end
  94.         end
  95.     end

2.2 Filter

  1.     class Filter < ActiveSupport::Callbacks::Callback #:nodoc:
  2.       def before?
  3.         self.class == BeforeFilter
  4.       end
  5.       def after?
  6.         self.class == AfterFilter
  7.       end
  8.       def around?
  9.         self.class == AroundFilter
  10.       end
  11.       private
  12.         def should_not_skip?(controller)
  13.           if options[:skip]
  14.             #:skip选项中不包含设定的方法就不能skip 
  15.             # 其中option[:skip]包含的结构也是一个包含:only :except的hash
  16.             !included_in_action?(controller, options[:skip]) 
  17.           else
  18.             true
  19.           end
  20.         end
  21.         def included_in_action?(controller, options) #判断该controller哪些是要加filter的
  22.           if options[:only]
  23.             Array(options[:only]).map(:to_s).include?(controller.action_name) #:only包含的是需要
  24.           elsif options[:except]
  25.             !Array(options[:except]).map(:to_s).include?(controller.action_name) #:except不用加
  26.           else
  27.             true
  28.           end
  29.         end
  30.         def should_run_callback?(controller) # 没有skip并且设定了的都要运行
  31.           should_not_skip?(controller) && included_in_action?(controller, options) && super
  32.         end
  33.     end

2.3 AroundFilter

 

  1.    class AroundFilter < Filter #:nodoc:
  2.       def type
  3.         :around
  4.       end
  5.       def call(controller, &block)
  6.         if should_run_callback?(controller)
  7.           method = filter_responds_to_before_and_after? ? around_proc : self.method
  8.           # For around_filter do |controller, action| 全部采用Proc方法运行
  9.           if method.is_a?(Proc) && method.arity == 2
  10.             evaluate_method(method, controller, block)
  11.           else
  12.             evaluate_method(method, controller, &block)
  13.           end
  14.         else
  15.           block.call
  16.         end
  17.       end
  18.       private
  19.         # 看看是否实现了before和after方法
  20.         def filter_responds_to_before_and_after?
  21.           method.respond_to?(:before) && method.respond_to?(:after)
  22.         end
  23.         # 将controller参数的before方法和after方法构建成Proc
  24.         def around_proc
  25.           Proc.new do |controller, action|
  26.             method.before(controller)
  27.             if controller.send!(:performed?)
  28.               controller.send!(:halt_filter_chain, method, :rendered_or_redirected) # 如果rendered_or_redirected就停止
  29.             else
  30.               begin
  31.                 action.call
  32.               ensure
  33.                 method.after(controller)
  34.               end
  35.             end
  36.           end
  37.         end
  38.     end

2.4  BeforeFilter

  1.     class BeforeFilter < Filter #:nodoc:
  2.       def type
  3.         :before
  4.       end
  5.       def call(controller, &block)
  6.         super
  7.         if controller.send!(:performed?)
  8.           controller.send!(:halt_filter_chain, method, :rendered_or_redirected) # 如果rendered_or_redirected就停止
  9.         end
  10.       end
  11.     end

2.5 AfterFilter

  1.     class AfterFilter < Filter #:nodoc:
  2.       def type
  3.         :after
  4.       end
  5.     end

3 总结

这次分析了几种Filter的具体代码实现,算是比较清楚了。

明天接着看如何加入到Controller

数据挖掘实战:决策树 + 聚类 + 关联规则,零 Key 离线可跑(Python 源码) 数据挖掘实战包。用 Python 标准库实现 CART 风格决策树、K-Means 聚类与 Apriori 关联规则,在虚构「星河便利店」会员表和购物篮上跑通分类、分群与购物篮分析,并给出准确率、轮廓系数、支持度/置信度/提升度。零第三方依赖、零 API Key 即可离线跑通。含 4 个样例、离线冒烟、中文 README(含「使用方法」)。均为作者原创可运行源码。MIT。作者 blog.youkuaiyun.com/mtl1994 立即下载

相关推荐

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

rails里的filter

before_filter after_filter around_filter 设置filter的参数可以为一个方法symbol :method_a ,一个block 或者一个类, 该类的静态方法self.filter()会被调用 默认filter作用于当前类的所有action方法和子类的action方法, :only 和 :except用来在controller中包含或者排除action

琉璃BES 1181

国央企创新负责人如何快速掌握本地科技资源分布与匹配情况?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

Rails源代码分析(7):ActionController::Filter(1)

Filter类似于钩子方法,在调用某个controller方法之前、之后或者包围调用这个方法,很有用的方法,利用这个可以很大幅度的减少代码量。1 先研究下种类:1.1 before_filter 多用于验证之类的    #     before_filter :verify_credentials    #    #     private    #       def verify_creden

jlaky的专栏 1630

国央企创新负责人如何实现科技成果的精准识别与高效筛选?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

FreeRTOS --(15)信号量之概述

FreeRTOS 中使用信号量来做同步,信号量可以在任务中使用作为任务与任务间的同步,也可以在中断中使用(带 FromISR 的版本)中断与任务间的同步; 针对不同的应用场景,信号量分为两种: 1、二值信号量; 2、计数信号量; 1、二值信号量 1.1、Usage 顾名思义,二值信号量只有两个值:0 和 1;它用于简单场景下的任务与任务、中断与任务之间的同步,比如:一个任务,在等待某个资源到位后,才能够继续执行,在得到这个资源之前,它处于阻塞状态,假如一个中断来了,给出了这个资源,那么.

StephenZhou 6517

Rails源代码分析(9):ActionController::Filter(3)

主要看看如何添加到ActionController的1 ClassMethods    module ClassMethods           ########################################      # The passed filters will be appended to the filter_chain and      # will ex

jlaky的专栏 679

高德地图开放平台Web服务API调用全解析:从申请Key到获取POI数据的完整流程

本文详细解析高德地图开放平台Web服务API的合规使用流程,从开发者账号注册、Key类型选择到POI数据采集方案构建。重点介绍文本搜索接口的三种查询模式及高级筛选技巧,提供配额管理与性能优化方案,并分享商业应用场景实战经验,帮助开发者合法高效获取POI数据。

weixin_26950847的博客 1350

Rails源代码分析(5):ActionController概览

ActionControlle的组成:ActionController::Base.class_eval do  include ActionController::Flash  include ActionController::Filters  include ActionController::Layout  include ActionController::Benchmarking  i

jlaky的专栏 569

MATLAB R2022b 安装教程

1. 下载安装先放资源链接,百度网盘太贵了不想续了,换了夸克网盘。1. 下载安装。

qq_51654158的博客 2万+

PHP特性知识点总结

(1)类型转换之前提到过的是字符串转为整型。其实php手册里面提到了各种类型的转换。先把他放在这里。我们按照php手册上的顺序来介绍,只介绍几个比较常用的。①转化为bool②转化为整型int。

m0_73605862的博客 1295

Rails源代码分析(23):ActionController::Verification

1 使用这个Module提供了一个类级别方法,验证某个方法就是指定的先决条件。可以看作是一个特别的before_filter       class GlobalController     #     # Prevent the #update_settings action from being invoked unless    #     # the admin_privileges 

jlaky的专栏 506

删除结点

对给定的单链表 L ,设计一个算法,删除 L 中值为 x 的结点的直接前驱结点。 1 由键盘输入值,换行表示输入结束,根据输入建立单链表。 2 输入链表中的一个元素值,从链表中删除这个元素的前驱结点。 3 对删除元素后的链表元素在屏幕上显示。 测试用例1 11 22 33 44 55 66 77↵ 44↵ 期待输出1 11 22 44 55 66 77↵ #include <iostre...

SChenlyx 1618

Rails源代码分析(18):ActionController::Caching(2) ActionCache

1 概述cache机制分为5个Module实现Pages, Actions, Fragments, Sweeping, SqlCache2 使用今天先看看ActionCache:Action Cache和Page Cache的相同之处在于-整个输出被cache起来了,但是两者的区别在于-Action Cache每个请求仍然会经过整个Action Pack,这个cache的好处在于在访问页面之前,f

jlaky的专栏 603

基于MYD-YT153与AD7616的16通道高速ADC采集系统实战指南

在嵌入式系统与工业数据采集领域,模拟信号采集是连接物理世界与数字系统的关键技术。其核心原理是通过模数转换器(ADC)将连续的模拟电压信号转换为离散的数字码值,供处理器处理。这项技术的价值在于实现了对温度、压力、振动等关键物理量的精确感知与数字化,是工业自动化、设备监测、科学实验等场景的基石。本文聚焦于**多通道**、**高精度**采集这一常见需求,深入剖析如何利用全志T153处理器的LocalBus并行总线接口,高效驱动ADI的16位、16通道同步采样ADC芯片AD7616,构建一个稳定可靠的高速数据采集系

weixin_30335353的博客 443

别再乱设阻尼了!Abaqus动力分析中瑞利阻尼的α和β到底怎么算?

本文深入解析Abaqus动力分析中瑞利阻尼参数α和β的科学计算方法,帮助工程师准确设置阻尼参数以提升仿真精度。详细介绍了基于模态阻尼比的经典计算方法和多模态优化法,并结合工程案例演示参数设置流程,避免常见的阻尼设置误区。

weixin_42634811的博客 731

CVE-2019-5418漏洞剖析:Rails任意文件读取原理与实战复现

路径遍历(Path Traversal)是Web安全中一种经典的高危漏洞类型,其核心原理在于应用程序未对用户输入的文件路径参数进行充分的安全校验,导致攻击者能够通过构造包含“../”等特殊字符的序列,突破预期的目录限制,访问或读取服务器文件系统中的任意文件。这种漏洞的技术价值在于其利用门槛相对较低,但危害性极高,可直接导致敏感信息泄露,如数据库凭证、应用程序源码和系统配置文件,常被作为网络渗透的初始突破口。在常见的Web应用框架中,此类问题常出现在文件渲染、模板包含或静态资源处理等环节。以Ruby on R

weixin_30376509的博客 364

以 Cloud 为核心的设备 mTLS 证书体系:从产品需求到 OP-TEE 安全落地

本文探讨了以云端为核心的物联网设备mTLS证书体系构建方案。文章从产品需求出发,分析了云端必须采用mTLS+证书体系管理设备身份的原因,指出静态Token方案的三大缺陷:身份不可控、运营不可控和审计不可控。重点阐述了mTLS在产品中的核心功能是加密传输和双向认证,并详细列出了云端PKI、设备注册中心等必备组件。在设备侧,强调必须通过OP-TEE技术保护私钥安全,提出了一个包含密钥生成、CSR导出等功能的TA设计方案。最后,文章给出了云端端到端流程示例,说明如何将证书生命周期管理转化为可运营的产品能力,包括自

Interview_TC的博客 641

Rails源代码分析(41):ActionView 概览

require action_view/template_handlerrequire action_view/template_handlers/compilablerequire action_view/template_handlers/builderrequire action_view/template_handlers/erbrequire action_view/t

jlaky的专栏 2034

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Rails源代码分析(1):RailsFCGIHandler

按照顺序从CGI开始入手Ruby CGI Doc:The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP request from a web server to a standalone program, and returning the output to the web browser.

jlaky的专栏 1968

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Rails源代码分析(15):ActionController::Helpers

1 如何使用默认情况下MyController自动包含MyHelper,add_template_helper 方法可以用来添加自定义的helper Module如果想另外添加,可以用 helper 方法来指定:    # ==== Examples    # The +to_s+ method from the Time class can be wrapped in a helper meth

jlaky的专栏 1369

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Rails源代码分析(14):ActionController::MimeResponds

什么是MimeRespondsMimeResponds主要是为了支持Web Service请求:比如 /people/list.html 返回一个html格式的响应比如 /people/list.xml 返回xml格式的响应Rails determines the desired response format from the HTTP Accept header submitted by th

jlaky的专栏 818

Rails源代码分析(2):分发器 Dispatcher

写了两遍~ 受不了这个网站      # Backward-compatible class method takes CGI-specific args. Deprecated      # in favor of Dispatcher.new(output, request, response).dispatch.      def dispatch(cgi = nil, session_op

jlaky的专栏 803

Rails源代码分析(11):ActionController::Layout(2)

    module ClassMethods      # If a layout is specified, all rendered actions will have their result rendered      # when the layout yields. This layout can itself depend on instance variables assigne

jlaky的专栏 589

Rails源代码分析(20):ActionController::Caching(4) FragmentCache

1 应用Fragment是用来cache一个block的时候使用的,常用于一个页面的页面一部分变化,一部分不变化的情况,       Hello @name %>       do %>         All the topics in the system:         :partial => "topic", :collection => Topic.find(:all) %>     

jlaky的专栏 584
上一篇: Rails源代码分析(7):ActionController::Filter(1)
下一篇: Rails源代码分析(9):ActionController::Filter(3)
jlaky
博客等级 码龄19年 5粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值