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 “SOAPMessageContext.getHeaders() Method”,它将返回一个包含指定 SOAP 标头的 JAXB 对象的数组。

例 43.10. SOAPMessageContext.getHeaders() Method

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

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

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

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

使用上下文属性

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

与应用程序的消息上下文一样,SOAP 消息上下文是 Java 映射的子类。要访问存储在上下文中的属性,请使用 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. 向 Apache CXF 运行时返回 true 信号,消息处理应正常继续。下一个处理程序(若有)对其 handleMessage() 调用。
  2. 向 Apache CXF 运行时返回 false 的信号,以停止正常消息处理。运行时进行的处理方式取决于用于 当前消息的消息 交换模式。

    请求响应消息会交换以下内容:

    1. 消息处理方向会被反转。

      例如,如果请求由服务提供商处理,则消息将停止进入服务的实施对象。相反,它将发回一个绑定,以返回源自请求的使用者。

    2. 任何驻留在处理程序链中的消息处理程序都会按照它们驻留在链中的顺序调用它们的 handleMessage() 方法。
    3. 当消息到达处理器链的末尾时,它将被发送。

      对于单向信息会交换以下内容:

    4. 消息处理停止.
    5. 所有之前调用的消息处理程序都具有其 close() 方法调用。
    6. 消息被发送。
  3. 引发 ProtocolException 异常异常,或者此异常的子类发送一个 Apache CXF 运行时,会向 Apache CXF 运行时发出错误消息处理。运行时进行的处理方式取决于用于 当前消息的消息 交换模式。

    请求响应消息会交换以下内容:

    1. 如果处理程序还没有创建错误消息,则运行时会将消息嵌套在错误消息中。
    2. 消息处理方向会被反转。

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

    3. 任何驻留在处理程序链的任何消息处理程序都会在 其处理 方向中调用的顺序按照它们驻留在链中的顺序调用。
    4. 当错误消息到达处理器链的末尾时,它将被发送。

      对于单向信息会交换以下内容:

    5. 如果处理程序还没有创建错误消息,则运行时会将消息嵌套在错误消息中。
    6. 消息处理停止.
    7. 所有之前调用的消息处理程序都具有其 close() 方法调用。
    8. 分配故障消息。
  4. 引发任何其他运行时例外 - 加一个协议Exception 异常异常阻止了消息处理停止的 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 消息。

将消息打印到控制台。