第 55 章 Apache CXF 运行时的拦截器
摘要
Apache CXF 运行时的大部分功能由拦截器实施。Apache CXF 运行时创建的每个端点包含三个处理消息的潜在拦截器链。这些链中的拦截器负责在线路和端点实施代码处理的 Java 对象之间转换原始数据传输的消息。拦截器被分为阶段,以确保处理正确顺序正确。
概述
Apache CXF 确实需要处理消息的一大部分。当消费者向远程服务调用时,运行时需要将数据放入服务可以使用的消息中,并将其放置在线路上。服务提供商必须联合该消息,执行其业务逻辑,并将响应引入到适当的消息格式。然后,消费者必须解除响应消息,将其与正确的请求相关联,然后将它传回消费者的应用代码。除了基本 marshaing 和 unmarshaling,Apache CXF 运行时还可通过消息数据执行许多其他事务。例如,如果激活 WS-RM,则运行时必须处理消息块并在放送和解放消息前确认消息。如果激活了安全性,则运行时必须验证消息的凭据,作为消息处理序列的一部分。
图 55.1 “Apache CXF 拦截器链” 显示服务提供程序收到请求时请求消息的基本路径。
图 55.1. Apache CXF 拦截器链
Apache CXF 中的消息处理
当 Apache CXF 开发的消费者调用远程服务时,以下消息处理序列已启动:
- Apache CXF 运行时会创建一个出站拦截器链来处理请求。
- 如果调用启动双向消息交换,则运行时会创建一个入站拦截器链和故障处理拦截器链。
请求消息会按顺序通过出站拦截器链传递。
链中的每个拦截器都会对消息执行一些处理。例如,Apache CXF 提供的 SOAP 拦截器打包了 SOAP envelope 中的消息。
如果出站链上的任何拦截器都创建一个错误,则链没有找到,并且控制权返回到应用程序级别代码。
拦截器链通过在之前调用的所有拦截器上调用 fault 处理方法,从而无法发现。
- 请求被分配给适当的服务供应商。
收到响应后,它将按顺序通过入站拦截器链进行传递。
注意如果响应是错误消息,它将传递到 fault 处理拦截器链。
- 如果入站链上的任何拦截器都创建一个错误条件,则链将不找到。
- 当消息到达入站拦截器链的末尾时,它会返回到应用程序代码。
当 Apache CXF 开发的服务供应商从消费者收到请求时,会发生类似的过程:
- Apache CXF 运行时会创建一个入站拦截器链来处理请求消息。
- 如果请求是双向消息交换的一部分,则运行时还会创建出站拦截器链和故障处理拦截器链。
- 请求通过入站拦截器链顺序传递。
如果入站链上的任何拦截器创建了错误条件,则链将不找到,并将错误分配给消费者。
拦截器链通过在之前调用的所有拦截器上调用 fault 处理方法,从而无法发现。
- 当请求到达入站拦截器链的末尾时,它将传递到服务实施。
当响应就绪时,它会按顺序通过出站拦截器链传递。
注意如果响应是异常,它将通过错误处理拦截器链进行传递。
- 如果出站链上的任何拦截器创建了错误条件,则链将不找到,并且会分配错误消息。
- 请求到达出站链的末尾后,它将被分配给消费者。
拦截器
Apache CXF 运行时中的所有消息处理都由 拦截器 来完成。拦截器是可在将消息数据传递给应用程序层前访问消息数据的 POJO。它们可以做多个事情,包括:转换消息的消息、剥离消息的标头,或者验证消息数据。例如,拦截器可以读取消息的安全标头,针对外部安全服务验证凭证,并决定消息处理是否可以继续。
拦截器可用的消息数据由多个因素决定:
- 拦截器链
- 拦截器阶段
- 前面在链中发生的其他拦截器
阶段
拦截器分为 阶段。阶段是包含通用功能的拦截器的逻辑分组。每个阶段负责特定类型的消息处理。例如,处理传递给应用程序层的 marshaled Java 对象的拦截器都会在同一阶段发生。
拦截器链
阶段会聚合为 拦截器链。拦截器链是根据消息是入站还是出站排序的拦截器阶段列表。
使用 Apache CXF 创建的每个端点有三个拦截器链:
- 入站消息的链
- 出站消息的链
- 用于错误消息的链
拦截器链主要由端点选择使用的绑定和传输组成。添加其他运行时功能,如安全或日志记录,也会在链中添加拦截器。开发人员也可以使用配置将自定义拦截器添加到链中。
开发拦截器
无论它的功能如何,开发拦截器始终遵循相同的基本步骤:
Apache CXF 提供多个抽象拦截器,以便更轻松地开发自定义拦截器。
拦截器需要某些消息的部分可用,并且需要以特定格式提供数据。信息的内容及数据格式部分由拦截器的阶段决定。
通常,阶段内拦截器的排序并不重要。但是,在某些情况下,确保拦截器在相同阶段之前或之后执行也可能非常重要。
- 第 58.2 节 “处理消息”
如果在拦截器执行后在活跃的拦截器链中发生错误,则会调用其错误处理逻辑。
- 第 59 章 配置端点以使用拦截器