0

我正在研究 SoapHandler 的实现。基本上我的目标是获取请求和响应有效负载并将它们插入数据库。

虽然我可以获得请求和响应有效负载,但我无法确定我的代码是否工作线程安全。换句话说,我不确定响应是否与正确的请求匹配。

public boolean handleMessage(SOAPMessageContext mContext) {

    boolean isResponse = (Boolean) mContext
            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    if (!isResponse) {
        try {
            mContext.put("currentStream", new ByteArrayOutputStream());
            mContext.getMessage().writeTo((OutputStream) mContext.get("currentStream"));

        } catch (SOAPException | IOException e) {
            e.printStackTrace();
        }
    } else {
        try {
            mContext.getMessage().writeTo(
                    (OutputStream) mContext.get("currentStream"));
            System.out.println(((OutputStream) mContext.get("currentStream"))
                    .toString());
            ((OutputStream) mContext.get("currentStream")).flush();
        } catch (SOAPException | IOException e) {
            e.printStackTrace();
        }
    }

    return true;
}

我在 JCP 规范中发现了这一点:

9.3.3 处理程序实现注意事项

处理程序实例可以由 JAX-RPC 运行时系统池化。JAX-RPC 运行时系统认为特定处理程序的所有实例都是等效的,并且可以选择任何实例来处理特定消息。可以使用不同的处理程序实例来处理 MEP 的每条消息。处理程序链中的每个处理程序、MEP 中的每个消息或两者的任意组合都可以使用不同的线程。处理程序不应依赖线程本地状态来共享信息。处理程序应改为使用消息上下文,请参阅第 9.4 节。

9.4 消息上下文

使用消息上下文调用处理程序,该消息上下文提供访问和修改入站和出站消息以及管理一组属性的方法。使用不同类型的消息上下文调用不同类型的处理程序。9.4.1 和 9.4.2 节分别描述了 MessageContext 和 LogicalMessageContext。此外,JAX-RPC 绑定 12 可以为它们的特定协议绑定定义消息上下文子类型,该协议绑定提供对协议特定特征的访问。第 10.3 节描述了 JAX-RPC SOAP 绑定的消息上下文子类型。

http://download.oracle.com/otn-pub/jcp/jaxrpc-2.0-edr2-spec-oth-JSpec/jaxrpc-2_0-edr2-spec.pdf?AuthParam=1431341511_1ac4403a34d7db108bce79eda126df49

这是否意味着为每个请求创建一个新的 MessageContext 对象(在这种情况下,我认为代码将是线程安全的),或者相同的 MessageContext 对象可以用于多个请求(那么我的代码将不是线程安全的)。

任何帮助/替代解决方案将不胜感激。

4

1 回答 1

1

经验法则:根据定义,FooContext对象是上下文的,与特定的执行上下文相关。EJBContext与单个 EJB 相关;FacesContext与单个 Faces 请求上下文相关;SOAPMessageContext与单有关SOAPMessage。从 JSR-109 文档中:

容器必须在特定节点上的单个请求和响应或故障处理期间调用的所有 Handler 实例和目标端点共享相同的 MessageContext 实例。

因此,您可以确定每个请求都有一个 SOAPMessageContext实例。然而,在单个请求的上下文中,该实例是你的。所以问题真的是,你所说的“线程安全”是什么意思?您是否计划在每个请求期间让多个线程处理一个?我不推荐它SOAPMessageContext

编辑:虽然规范没有以黑白方式说明 aMessageContext是线程安全的,但在整个规范中都暗示了这一点。以下是规范部分的摘录,该部分说明MessageContext了处理程序中的 , 可能发生的事情:

处理程序可以根据需要操纵消息上下文中属性的值和范围。例如...服务器端 SOAP 绑定中的处理程序可能会从请求 SOAP 消息中的标头内容将应用程序范围的属性添加到消息上下文中...


SOAPMessageContextSOAP 处理程序在调用时传递。SOAPMessageContext扩展MessageContext获取和修改 SOAP 消息有效负载的方法

如果这样做不安全,规范不会期望程序员修改上下文的内容。

于 2015-05-13T06:20:32.193 回答