我有一个针对传入消息的自定义SOAP消息处理程序,它将根据正在调用的操作运行不同的代码。我第一次尝试获取操作名称看起来像这样:
public boolean handleMessage(SOAPMessageContext context)
{
String op = context.get(MessageContext.WSDL_OPERATION);
...
此操作失败,因为似乎永远不会设置属性MessageContext.WSDL_OPERATION
。然后我尝试使用它:
public boolean handleMessage(SOAPMessageContext context)
{
Map<?, ?> headers = (Map<?, ?>)context.get(MessageContext.HTTP_REQUEST_HEADERS);
ArrayList<String> SOAPAction = ((ArrayList<String>) headers.get("SOAPAction"));
String opName = SOAPAction.get(0);
//opName will be formatted like "urn#myOperation", so the prefix must be removed
opName = ((opName.replace("\"","").split("#"))[1]);
这样可行,但我担心可能会出现标题属性“SOAPAction”未设置(或甚至不存在)的情况,或者没有我期望的值。我也有点担心,因为我不知道这是否是获取操作名称的“官方”方式 - 我通过查看调试器中context
的内容来解决这个问题。
在处理传入的SOAP消息时,有没有更好的方法来获取操作名称?
答案 0 :(得分:5)
我参加这个派对的时间已经很晚了,但过去一周我试图这样做。接受的答案实际上并不适用于每个JAX-WS实现(至少不是我尝试过的)。
我一直在尝试在我的开发环境中使用独立Metro工作,但也在实际环境中使用与WebSphere 7捆绑在一起的Axis2。
我在Metro上找到了以下工作:
String operationName = body.getChildNodes().item(0).getLocalName();
以及以下适用于Axis2:
String operationName = body.getChildNodes().item(1).getLocalName();
发生的事情是Axis2将一个Text
类型的节点作为第一个孩子插入Body,但Metro不会。此文本节点返回null本地名称。我的解决方案是执行以下操作:
NodeList nodes = body.getChildNodes();
// -- Loop over the nodes in the body.
for (int i=0; i<nodes.getLength(); i++) {
Node item = nodes.item(i);
// -- The first node of type SOAPBodyElement will be
// -- what we're after.
if (item instanceof SOAPBodyElement) {
return item.getLocalName();
}
}
如评论中所述,我们实际上正在寻找SOAPBodyElement
类型的第一个节点。希望这将有助于其他人在将来看到这个。
答案 1 :(得分:4)
您可以调用body.getElementName().getLocalName()
来检索消息有效内容的SOAP body元素的名称。它有点冗长和手动,但它的工作原理。您可以在处理程序中包含以下内容
if ((boolean) context.get(MessageContext.MESSAGE_INBOUND_PROPERTY){ //for requests only
SOAPEnvelope msg = context.getMessage().getSOAPPart().getEnvelope(); //get the SOAP Message envelope
SOAPBody body = msg.getBody();
String operationName = body.getChildNodes().item(1).getLocalName();
}
上述代码的结果保证带有WSDL中指定的操作名称
编辑:此解决方案完全基于Web服务实现为document / literal-wrapped或RPC / literal的条件
答案 2 :(得分:1)
SOAPMessageContext包含此信息,可以像这样轻松检索:
public boolean handleMessage(SOAPMessageContext msgContext) {
QName svcn = (QName) smc.get(SOAPMessageContext.WSDL_SERVICE);
QName opn = (QName) smc.get(SOAPMessageContext.WSDL_OPERATION);
System.out.prinln("WSDL Service="+ svcn.getLocalPart());
System.out.prinln("WSDL Operation="+ opn.getLocalPart());
return true;
}
答案 3 :(得分:0)
如果有人搜索&#34;优雅&#34;获得所需属性的方法
for(Map.Entry e : soapMessageContext.entrySet()){
log.info("entry:"+ e.getKey() + " = " + e.getValue());
}
然后决定你需要什么信息并获得它!
soapMessageContext.get(YOUR_DESIRED_KEY);