43.5. 处理 SOAP 处理程序中的消息
概述
正常消息处理由 handleMessage ()
方法处理。
handleMessage ()
方法接收 SOAPMessageContext
对象,以 SOAPMessage
对象和与消息关联的 SOAP 标头提供对消息的访问。此外,上下文提供对消息上下文中存储的任何属性的访问。
handleMessage ()
方法返回 true 或 false,具体取决于消息处理如何继续。它还可能会抛出异常。
使用消息正文
您可以使用 SOAP 消息上下文的 getMessage ()
方法获取 SOAP 消息。它将消息返回为 live SOAPMessage
对象。处理程序中消息的任何更改都会自动反映在上下文中存储的消息中。
如果要将现有消息替换为新消息,您可以使用上下文的 setMessage ()
方法。setMessage ()
方法采用 SOAPMessage
对象。
获取 SOAP 标头
您可以使用 SOAPMessage
对象的 getHeader ()
方法访问 SOAP 消息的标头。这将返回 SOAP 标头作为 SOAPHeader
对象,您需要检查以查找您要处理的标头元素。
SOAP 消息上下文提供 getHeaders ()
方法,如 例 43.10 “SOAPMessageContext.getHeaders ()
方法” 所示,它将返回一个包含指定 SOAP 标头的 JAXB 对象的数组。
例 43.10. SOAPMessageContext.getHeaders ()
方法
Ojbect[]
getHeaders
QName
header
JAXBContext
上下文
布尔值
allRoles
您可以使用其元素的 QName 指定标头。您可以通过将 allRoles
参数设置为 false 来进一步限制返回的标头。这指示运行时仅返回适用于活动 SOAP 角色的 SOAP 标头。
如果没有找到标头,则方法会返回一个空数组。
有关实例化 JAXBContext
对象的更多信息,请参阅 第 39 章 使用 A JAXBContext
对象。
使用上下文属性
传递到逻辑处理程序的 SOAP 消息上下文是应用的消息上下文的实例,可以访问其中存储的所有属性。处理程序有权访问应用范围 和处理程序
范围的属性。
与应用程序的消息上下文一样,SOAP 消息上下文是 Java Map 的子类。要访问存储在上下文中的属性,您可以使用从 Map 接口继承的 get ()
方法和 put ()
方法。
默认情况下,您在逻辑处理程序内的上下文中设置的任何属性都会被分配 HANDLER
范围。如果您希望应用程序代码能够访问所需的属性,您需要使用上下文的 setScope ()
方法将属性明确设置为 APPLICATION。
有关在消息上下文中使用属性的详情,请参考 第 42.1 节 “了解上下文”。
确定消息的方向
知道消息通过处理程序链的方向通常非常重要。例如,您要将标头添加到传出消息,并从传入的消息中剥离标头。
消息的方向存储在消息上下文的出站消息属性中。您可以使用 MessageContext.MESSAGE_OUTBOUND_PROPERTY 密钥从消息上下文检索出站消息属性,如 例 43.11 “从 SOAP 消息上下文获取消息方向” 所示。
例 43.11. 从 SOAP 消息上下文获取消息方向
Boolean outbound; outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
属性作为 布尔值对象存储
。您可以使用对象的 booleanValue ()
方法来确定属性值。如果属性设为 true,则会出站消息。如果属性设为 false,则消息为 inbound。
确定返回值
handleMessage ()
方法如何完成其消息处理对消息处理的方式有直接影响。它可以通过执行以下操作之一完成:
-
将 true-Returning true 信号返回到消息处理应该继续正常运行的 Apache CXF 运行时。下一个处理程序(若有)调用了其
handleMessage ()
。 将 false-Returning false 信号返回到正常消息处理要停止的 Apache CXF 运行时。运行时的继续取决于用于 当前消息 的消息交换模式。
对于请求响应消息交换,会出现以下情况:
消息处理的方向被撤销。
例如,如果某个请求由服务提供商处理,则该消息将停止进入服务的实施对象。相反,它将发回到该绑定,以返回到源自请求的消费者。
-
在新处理方向中驻留在处理程序链的任何消息处理程序都按照它们位于链中的顺序调用其
handleMessage ()
方法。 当消息到达处理程序链的末尾时,会被分配。
对于单向消息交换会出现以下情况:
- 消息处理将停止。
-
所有之前调用的消息处理程序都具有其
close ()
方法调用。 - 消息被分配。
抛出一个 ProtocolException 异常,或者这个例外的子类,信号 Apache CXF 运行时会启动错误消息处理。运行时的继续取决于用于 当前消息 的消息交换模式。
对于请求响应消息交换,会出现以下情况:
- 如果处理程序尚未创建 fault 消息,则运行时会将消息嵌套在出错消息中。
消息处理的方向被撤销。
例如,如果某个请求由服务提供商处理,则该消息将停止进入服务的实施对象。它将发回到该绑定,以返回到源自请求的消费者。
-
在新处理方向中驻留在处理程序链的任何消息处理程序都按照它们位于链中的顺序调用其
handleFault ()
方法。 当故障消息到达处理程序链的末尾时,它将被分配。
对于单向消息交换会出现以下情况:
- 如果处理程序尚未创建 fault 消息,则运行时会将消息嵌套在出错消息中。
- 消息处理将停止。
-
所有之前调用的消息处理程序都具有其
close ()
方法调用。 - 已分配 fault 消息。
-
抛出任何其他运行时异常-浏览除 ProtocolException 异常之外的运行时异常,信号了消息处理要停止的 Apache CXF 运行时。所有之前调用的消息处理程序都有一个
close ()
方法,并分配异常。如果消息是请求响应消息交换的一部分,则会发送异常,使其返回到源自请求的消费者。
示例
例 43.12 “在 SOAP 处理程序中处理消息” 显示一个 handleMessage ()
实现,它将 SOAP 消息打印到屏幕。
例 43.12. 在 SOAP 处理程序中处理消息
public boolean handleMessage(SOAPMessageContext smc) { PrintStream out; Boolean outbound = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outbound.booleanValue()) { out.println("\nOutbound message:"); } else { out.println("\nInbound message:"); } SOAPMessage message = smc.getMessage(); message.writeTo(out); out.println(); return true; }
例 43.12 “在 SOAP 处理程序中处理消息” 中的代码执行以下操作:
从消息上下文检索 outbound 属性。
测试消息方向并打印适当的消息。
从上下文检索 SOAP 消息。
将消息输出到控制台。