我正在开发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 可以为其特定协议绑定定义消息上下文子类型,以提供对协议的访问 具体功能。 Section.10.3描述了JAX-RPC SOAP绑定的消息上下文子类型。
这是否意味着为每个请求创建了一个新的MessageContext对象(在这种情况下我认为代码是线程安全的),或者同一个MessageContext对象可以用于多个请求(那么我的代码将不是线程安全的)。
任何帮助/替代解决方案都将受到赞赏。
答案 0 :(得分:0)
经验法则:根据定义,FooContext
对象是上下文,与特定的执行上下文相关。 EJBContext
与单个EJB有关; FacesContext
与单个Faces请求上下文相关; SOAPMessageContext
与单个SOAPMessage
相关。来自JSR-109文档:
容器必须在所有Handler实例和在单个请求期间调用的目标端点以及特定节点上的响应或故障处理之间共享相同的MessageContext实例。
因此,您可以确定每个请求中有一个新的 SOAPMessageContext
实例 。但是,在单个请求的上下文中,该实例是您的实体。所以问题是,你是什么意思" threadsafety"?您是否计划在每个请求期间有多个线程处理单个SOAPMessageContext
?我不推荐它
编辑:虽然规范并未以黑白表示MessageContext
是线程安全的,但在整个规范中都暗示了这一点。以下是规范部分的摘录,其中说明了MessageContext
在处理程序中的可能性:
处理程序可以根据需要操纵消息上下文中的属性值和范围。例如。 ...服务器端SOAP绑定中的处理程序可能会从请求SOAP消息中的标头内容向消息上下文添加应用程序作用域属性...
SOAP调度程序在调用时传递
SOAPMessageContext
。SOAPMessageContext
使用方法扩展MessageContext
以获取和修改SOAP消息有效负载
如果没有安全的话,规范就不会期望程序员修改上下文的内容。