二、中间件(middleware)
1. 中间件(middleware)
Django中的中间件主要实现一些附加功能,在request被用户handler处理前,以及用户handler处理后生存的response进行处理。因此大部分中间件的主要功能是实现了process_request或者process_response之一,当然也可以两者都实现,意味着该中间件涉及到处理的request和response的处理。
1.1 类视图
在中间件的类关系中,基本类是MiddlewareMixin,其他所有的中间件类都继承自该类,该类仅有一个成员变量get_response,该变量在连接各个中间件起着非常重要的作用。该类有两个成员函数:__init__和__call__,前者用于实现初始化,后者执行主要的功能。
def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
response = self.process_request(request)
if not response:
response = self.get_response(request)
if hasattr(self, 'process_response'):
response = self.process_response(request, response)
return response
其中process_request和process_response自不必多言,中间件需要实现的主要功能,通过hasattr()调用,判断当前中间件是否具有process_request和process_response,有则调用。
不同功能的中间件,根据要完成的功能,可以扩展自己的成员变量和成员函数,通常,自定义的成员函数被process_request和process_response调用,即这些自定义的成员函数通常不对外开放。
其中,__init__成员函数有入参函数之一: get_response,这在后续的加载中间件时很重要好。
下图是中间件SecurityMiddleware类的类视图关系图,其他中间件的视图关系类似。
1.2 中间件初始化
在工程的配置文件(Project/Project/setting.py)中指定要使用的中间件,注意各插件在序列中的顺序,这决定了当请求到来时,各个中间件的执行顺序,排在最前面的中间件得到最先执行,最后的中间件最后执行。其表现通常如下所示:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
下面来看,中间件是如何被加载和初始化的。class BaseHandler(object):中定义了load_middleware接口,具体细节如下:
handler = convert_exception_to_response(self._get_response) /*handler[0]*/
for middleware_path in reversed(settings.MIDDLEWARE):
middleware =
import_string(middleware_path)
mw_instance = middleware(handler)
handler = convert_exception_to_response(mw_instance) /*handler[i]*/
self._middleware_chain = handler /*handler[end]*/
在上述例程中,开始遍历所有中间件之前,handler(即handler[0])赋值给调用实体的_get_response成员函数。 (比如class WSGIHandler(base.BaseHandler),WSGIHandler. load_middleware()调用之后,handler[0] = WSGIHandler._get_response = BaseHandler._get_response())。遍历所有中间件过程中,加载并初始化(middleware()调用对应着__init__成员函数)中间件,因此中间件的get_response赋值为handler[i],注意middleware()返回一个中间件类实体,接着调用调用handler = convert_exception_to_response (mw_instance),convert_exception_to_response只是对输入函数进行了容错封装,在分析逻辑时,可以简单看成输入函数本身,因此,可以看成handler = mw_instance(request),对于一个类实体调用即调用__call__成员函数,从目前来看,大部分的中间件并没有重载该成员函数,因此是直接调用基类的成员函数,即: MiddlewareMixin. __call__(self)。因此handler[i] = MiddlewareMixin. __call__(self)。注意该函数有一个self输入参数,各个中间件在调用时,传入该中间件对应的self实体,这样self.process_request, self.process_response的调用就分别对应着不同中间夹的处理函数。load_middleware()调用之后,各个中间件通过get_response链接起来,这样一个request请求到来时,可以顺序通过各个中间件依次进行处理,如下图所示:
在调用的最后,将self._middleware_chain = handler[end],类似于将中间件链表的链表头保存起来,下次处理时,从该链表头开始进行遍历处理。
1.3 中间件使用
各个中间件的调用顺序如下递归图所示:
在类视图一节中对__call__基类成员函数进行过介绍,该函数主要有先后执行的三个函数构成:process_request()、get_response()、process_response(),而get_response()通常指向下一个中间件的__call__成员函数(中间件链表的最后一个中间件除外,其get_response()指向handler[0]),由于各个中间件的get_response()这一特性(绝大部分指向基类__call__成员函数),使得中间件链表处理有点类似递归调用的感觉。A,B,A1,B1,A2,B2,C2,C1,C,这一递归调用顺序,决定了各个中间件处理的一些特点:
1、最先进行流程处理的中间件,其process_request()(如果存在的话)最先被执行,但是其process_response()(如果存在的话)却最后得到处理。
2、最后进行流程处理的中间件,其process_request()(如果存在的话)最后被执行,但是其process_response()(如果存在的话)紧接着得到处理。
3、在中间件处理流程中,如果出现某个中间件的process_request()返回了response,这种情况通常是处理过程中出现了异常情况,该中间件后续的中间件不再参与处理,直接调用该中间件的process_response()(如果存在的话),或者直接返回。
二、中间件(middleware)的更多相关文章
- C# Owin 创建与测试自己的中间件Middleware(二)
本文纯属介绍怎么简单地创建自己的Owin.还没有理解owin概念的请看上一篇文章:http://www.cnblogs.com/alunchen/p/7049307.html 目录 1.创建项目 2. ...
- ASP.NET Core -中间件(Middleware)使用
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...
- ASP.NET Core 开发-中间件(Middleware)
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
- ASP.NET Core中间件(Middleware)实现WCF SOAP服务端解析
ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Core整个WCF host. 因 ...
- laravel中间件-----------middleware
middleware中间件 是访问到达服务器后在被对应的路由处理之前所经过的一层过滤层,故称中间件. 中间件是存放在app\http\middleware中,需要定一个 handle 处理方法,在ha ...
- 中间件(Middleware)
中间件(Middleware) ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下 ...
- 初探中间件(middleware)
初探中间件(middleware) 因为考虑到文章的长度, 所以 BaseHandler 的展开被推迟了. 在 BaseHandler 中隐藏着中间件的信息, 较常见的 SessionMiddlewa ...
- django中间件Middleware
熟悉web开发的同学对hook钩子肯定不陌生,通过钩子可以方便的实现一些触发和回调,并且做一些过滤和拦截. django中的中间件(middleware)就是类似钩子的一种存在.下面我们来介绍一下,并 ...
随机推荐
- Linux 磁带机备份完全攻略
一.确定数据备份策略 首先必须确定在备份过程中操作哪些文件.在商业环境中,这是非常困难的一个决定,而且会产生严重的影响.如果备份了太多数据,会导致备份系统的成本过于庞大,会削减其他方面的开支.如果没有 ...
- Mac OSX - 如何在bash_profile中配置全局环境变量
我们知道,在Linux操作系统下,配置环境变量是使用如下命令: vim /etc/profile 在OSX下,我们用如下命令打开环境变量配置文件: open ~/.bash_profile 典型的环境 ...
- WebSocket桌面客户端工具
考虑到WebSocket的诸多优点和未来的趋势,去年底把服务端通讯全部由HTTP改成WebSocket,期间为了方便测试,做了这个小工具.共享出来以方便有同样需求的程序员. 下载的压缩包里含有源代码和 ...
- shell脚本编写方法
shell脚本编写就如同一门语言,涉及到运行环境.基本语法.变量定义.函数.参数(系统参数).条件判定.执行流程控制 等等问题. 本文就以下几个方面进行描述: 运行环境: shell shebang ...
- 根据第三方提供的wsdl报文(axis2开发),进行的webservice应用的开发实例
接口应用名称:NgCallService 入参和出参信息 入参和出参报文信息 入参: <?xml version="1.0" encoding="UTF-8&quo ...
- Lumia 830 win10m 启用触摸按键
用了一年半的830疑似翘屏… 按键基本失灵 每次按的时候基本都是 appbar 那里有反映… 实在懒于换手机(主要是不想花钱…) 研究下怎么启用虚拟按键,还能再战几年… 启用虚拟按键 其实简单说法就是 ...
- 【转帖】四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho
四种BI 开源工具介绍-SpagoBI,openI,JasperSoft,Pentaho 1 BI系统的简述 从技术角度来说 BI 包含了 ETL.DW.OLAP.DM等多环节.简单的说就是把交易系统 ...
- SPF 简介
SPF 简介 摘要: SPF 是发送方策略框架 (Sender Policy Framework) 的缩写,希望能成为一个防伪标准,来防止伪造邮件地址.这篇文章对 SPF 进行了简单介绍,并介绍了它的 ...
- 开发常用到的terminal命令
1.删除work_plugin目录下的.svn文件(最后面的;也是命令的一部分) sudo find /Users/maxinliang/DaTang/work_plugin ".svn&q ...
- [转]UML八大误解
潘加宇 本文删节版发表于<程序员>2013年11期 UML(统一建模语言)是软件建模的表示法标准.我从2002年开始专门从事研究和推广UML的工作,在为软件组织提供UML相关需求和设计技能 ...