【发布时间】:2011-11-20 08:24:07
【问题描述】:
如何从轴客户端的soap头中删除mustunderstand属性。即使我没有特别设置它,当我设置soap头信息mustundertand并且actor属性会自动添加到soap消息中。有人知道如何删除它们吗? 我正在使用 Axis2 1.4 版本的 wsdl2java 来创建我的 ws 客户端。
【问题讨论】:
如何从轴客户端的soap头中删除mustunderstand属性。即使我没有特别设置它,当我设置soap头信息mustundertand并且actor属性会自动添加到soap消息中。有人知道如何删除它们吗? 我正在使用 Axis2 1.4 版本的 wsdl2java 来创建我的 ws 客户端。
【问题讨论】:
这些解决方案都不适合我,因为:
查看“Adding ws-security to wsdl2java generated classes”的答案帮助我编写了一个适合我的解决方案:
void addSecurityHeader(Stub stub, final String username, final String password) {
QName headerName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security"); // Or any other namespace that fits in your case
AtomicReference<SOAPHeaderElement> header
= new AtomicReference<SOAPHeaderElement>
(new SOAPHeaderElement(headerName) {
{
SOAPElement utElem = addChildElement("UsernameToken");
utElem.addChildElement("Username").setValue(username);
utElem.addChildElement("Password").setValue(password);
}
@Override
public void setAttribute(String namespace, String localName, String value) {
if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) { // Or any other attribute name you'd want to avoid
super.setAttribute(namespace, localName, value);
}
}
});
SOAPHeaderElement soapHeaderElement = header.get();
soapHeaderElement.setActor(null); // No intermediate actors are involved.
stub.setHeader(soapHeaderElement); // Finally, attach the header to the stub
}
【讨论】:
如果您想在您拥有的 AXIS 客户端中禁用必须了解的检查 将以下行添加到您的代码中:
_call.setProperty(Call.CHECK_MUST_UNDERSTAND, new Boolean(false));
那么永远不会调用 AXIS 客户端的 MustUnderstandChecker。
【讨论】:
在我的情况下,它可以手动从 SOAPHeader
中删除该属性SOAPHeader header = env.getHeader();
OMChildrenQNameIterator childrenWithName = (OMChildrenQNameIterator) header.getChildrenWithName(omElementauthentication.getQName());
while (childrenWithName.hasNext()) {
org.apache.axiom.om.OMElement omElement = (org.apache.axiom.om.OMElement) childrenWithName.next();
QName mustAnderstandQName = omElement.resolveQName("soapenv:mustUnderstand");
if (mustAnderstandQName == null) {
continue;
}
OMAttribute mustAnderstandAttribute = omElement.getAttribute(mustAnderstandQName);
if (mustAnderstandAttribute == null) {
continue;
}
omElement.removeAttribute(mustAnderstandAttribute);
}
【讨论】:
我最近遇到了类似的情况,通过谷歌搜索,我设法找到了以下解决方案。
使用过 Axis2,您可能已经生成了一个 MyWSStub 文件,其中包含对您的服务的调用。 创建一个扩展您的存根的包装类(最好不要触摸自动生成的存根文件),例如MyWSStubWrapper:
public class MyWSStubWrapper extends MyWSStub {
/**
* @throws AxisFault
*/
public MyWSStubWrapper() throws AxisFault {
}
/**
* @param configurationContext
* @throws AxisFault
*/
public MyWSStubWrapper(ConfigurationContext configurationContext) throws AxisFault {
super(configurationContext);
}
/**
* @param targetEndpoint
* @throws AxisFault
*/
public MyWSStubWrapper(String targetEndpoint) throws AxisFault {
super(targetEndpoint);
}
/**
* @param configurationContext
* @param targetEndpoint
* @throws AxisFault
*/
public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint) throws AxisFault {
super(configurationContext, targetEndpoint);
}
/**
* @param configurationContext
* @param targetEndpoint
* @param useSeparateListener
* @throws AxisFault
*/
public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint, boolean useSeparateListener) throws AxisFault {
super(configurationContext, targetEndpoint, useSeparateListener);
}
@Override
protected void addHeader(OMElement omElementToadd, SOAPEnvelope envelop, boolean mustUnderstand) {
SOAPHeaderBlock soapHeaderBlock = envelop.getHeader().addHeaderBlock(omElementToadd.getLocalName(), omElementToadd.getNamespace());
OMNode omNode = null;
// add child elements
for (Iterator iter = omElementToadd.getChildren(); iter.hasNext();) {
omNode = (OMNode) iter.next();
iter.remove();
soapHeaderBlock.addChild(omNode);
}
OMAttribute omatribute = null;
// add attributes
for (Iterator iter = omElementToadd.getAllAttributes(); iter.hasNext();) {
omatribute = (OMAttribute) iter.next();
soapHeaderBlock.addAttribute(omatribute);
}
}
}
请记住,上面的代码将从您的标题中完全删除soapenv:mustUnderstand="0|1" 如果您想添加您需要调用soapHeaderBlock.setMustUnderstand(true|false);代码中的某处。
【讨论】:
1) 您是否使用了 Axis SOAPHeaderElement,如果是,您是否将 mustUnderstand 设置器设置为 false?
2) 由于您使用 wsdl2java 生成客户端,因此 WSDL(或更准确地说,模式)很可能在 SOAP 绑定中引用的元素上包含 mustUnderstand 属性。所以当wsdlToJava生成客户端代码的时候,那些属性自然会加进去。有关 mustUnderstand 属性的说明,请参见 here。 如果修改 WSDL 是不可能的,并且您必须从标头中删除此属性,那么我想您可以尝试使用处理程序来做到这一点
3) 不可取,但如果您真的必须删除此属性,那么我想您可以添加一个更改标头的客户端处理程序:http://ws.apache.org/axis/java/apiDocs/org/apache/axis/handlers/package-summary.html
【讨论】:
我正在使用带有 ws 安全性的轴 1.4 客户端
就我而言,正如莱因哈德所说 这行得通
MyService service = new MyServiceLocator();
MyServicePortType port = service.getMyServiceHttpsSoap11Endpoint();
((Stub) port)._setProperty(Call.CHECK_MUST_UNDERSTAND, Boolean.FALSE);
【讨论】: