43.5. 在 SOAP 处理程序中处理消息

概述

普通消息处理由 handleMessage () 方法处理。

handleMessage () 方法收到 SOAPMessageContext 对象,它以 SOAPMessage 对象和与该消息关联的 SOAP 标头来提供对消息的访问。此外,上下文还提供对消息上下文中存储的任何属性的访问。

根据消息处理方式,handleMessage () 方法返回 true 或 false。它还可能会抛出异常。

使用消息正文

您可以使用 SOAP 消息上下文的 getMessage () 方法来获取 SOAP 消息消息。它将消息返回为实时 SOAPMessage 对象。处理程序中消息的任何更改都会自动反映到存储位置的消息中。

如果要将现有消息替换为新消息,您可以使用上下文的 setMessage () 方法。setMessage () 方法采用 SOAPMessage 对象。

获取 SOAP 标头

您可以使用 SOAPMessage 对象的 getHeader () 方法访问 SOAP 消息的标头。这会将 SOAP 标头返回为 SOAPHeader 对象,您将需要检查 来查找您要处理的标头元素。

SOAP 消息上下文提供 getHeaders () 方法,如 例 43.10 “The SOAPMessageContext.getHeaders() Method” 所示,这将返回一个包含指定 SOAP 标头的 JAXB 对象的数组。

例 43.10. The SOAPMessageContext.getHeaders() Method

Ojbect[]getHeadersQName标头JAXBContext上下文布尔值allRoles

您可以使用其元素的 QName 指定标头。您可以通过将 allRoles 参数设置为 false 来进一步限制返回的标头。这指示运行时只返回适用于活跃 SOAP 角色的 SOAP 标头。

如果没有找到标头,方法会返回一个空数组。

有关实例化 JAXBContext 对象的更多信息,请参阅 第 39 章 使用 A JAXBContext 对象

使用上下文属性

传递到逻辑处理程序的 SOAP 消息上下文是应用程序消息上下文的实例,可以访问其中存储的所有属性。处理程序可以访问 APPLICATION 范围和 Handler 范围中的属性。

与应用程序的消息上下文一样,SOAP 消息上下文是 Java map 的子类。若要访问上下文中存储的属性,您可以使用 get () 方法和从 Map 接口继承的 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,则消息为入站。

确定返回值

handleMessage () 方法完成其消息处理对消息处理方式具有直接影响。它可以通过以下操作之一完成:

  1. 返回 true-Returning true 信号到消息处理应继续的 Apache CXF 运行时。下一个处理程序(若有)已调用了其 handleMessage ()
  2. 将 false-Returning false 信号返回到普通消息处理可停止的 Apache CXF 运行时。运行时的执行方式取决于用于 当前消息 的消息交换模式。

    对于请求响应的消息会交换以下情况:

    1. 消息处理的方向将被逆向。

      例如,如果请求由服务提供商处理,消息将停止提升到服务的实施对象。相反,它将退回到该绑定,以返回源自请求的使用者。

    2. 在新的处理方向中驻留在处理程序链的任何消息处理程序都会以它们驻留在链中的顺序调用其 handleMessage () 方法。
    3. 当消息到达处理程序链的末尾时,它将被分配。

      对于单向消息交换以下情况:

    4. 消息处理将停止。
    5. 所有之前调用的消息处理程序都具有其 close () 方法调用。
    6. 邮件被发送。
  3. 引发 ProtocolException 异常异常或此异常的子类,以指出消息处理是启动的 Apache CXF 运行时。运行时的执行方式取决于用于 当前消息 的消息交换模式。

    对于请求响应的消息会交换以下情况:

    1. 如果处理程序尚未创建错误消息,则运行时会将消息嵌套在容错消息中。
    2. 消息处理的方向将被逆向。

      例如,如果请求由服务提供商处理,消息将停止提升到服务的实施对象。它将发回给该绑定,以返回源自请求的使用者。

    3. 在新的处理方向中驻留在处理程序链的任何消息处理程序都会以它们驻留在链中的顺序调用其 handleFault () 方法。
    4. 当故障消息到达处理程序链的末尾时,它将被分配。

      对于单向消息交换以下情况:

    5. 如果处理程序尚未创建错误消息,则运行时会将消息嵌套在容错消息中。
    6. 消息处理将停止。
    7. 所有之前调用的消息处理程序都具有其 close () 方法调用。
    8. 将发送错误信息。
  4. 抛出任何其他运行时异常 - 除 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 处理程序中处理消息” 中的代码执行以下操作:

从消息上下文检索出站属性。

测试消息方向并输出正确的消息。

从上下文检索 SOAP 消息。

将信息打印到控制台。