我正在尝试SOAPHandler
在我的服务器上设置一个来转换这个传入的请求
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<getMachine xmlns="http://machine.soap.webservices.product.company.at/">
<machineId>92623-15853588</machineId>
</getMachine>
</S:Body>
</S:Envelope>
对这个要求。
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<enns1:getMachine xmlns:enns1="http://machine.soap.webservices.product.company.at/">
<machineId>92623-15853588</machineId>
</enns1:getMachine>
</S:Body>
</S:Envelope>
我的 SOAPHandler 看起来像这样。
package at.company.product.webservices.soap;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class SOAPValidationHandler implements SOAPHandler<SOAPMessageContext> {
private static final String PREFIX = "enns1";
@Override
public boolean handleMessage(SOAPMessageContext context) {
System.out.println("Server : handleMessage()......");
Boolean isRequest = (Boolean) context
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// inbound
if (!isRequest) {
try {
SOAPMessage soapMsg = context.getMessage();
SOAPBody body = soapMsg.getSOAPBody();
Iterator<SOAPElement> it = body.getChildElements();
// Look for all body elements who have a "xmlns" attribute and
// add a namespace prefix to it
while (it.hasNext()) {
SOAPElement elem = it.next();
addNamespacePrefix(elem);
Iterator itChildren = elem.getChildElements();
while (itChildren.hasNext()) {
Object child = itChildren.next();
if (child instanceof SOAPElement) {
SOAPElement cElem = ((SOAPElement) child);
// TODO: Remove the namespace from the child
// cElem.removeNamespaceDeclaration(""); => Does not
// work
}
}
}
// tracking
soapMsg.writeTo(System.out);
} catch (SOAPException e) {
System.err.println(e);
} catch (IOException e) {
System.err.println(e);
}
}
return true;
}
private void addNamespacePrefix(SOAPElement elem) throws SOAPException {
Iterator<Object> it = elem.getAllAttributes();
QName name = new QName("xmlns");
String value = elem.getAttributeValue(name);
if (value != null) {
elem.addNamespaceDeclaration(PREFIX, elem.getNamespaceURI());
elem.removeNamespaceDeclaration("");
elem.setPrefix(PREFIX);
}
}
@Override
public boolean handleFault(SOAPMessageContext context) {
System.out.println("Server : handleFault()......");
return true;
}
@Override
public void close(MessageContext context) {
System.out.println("Server : close()......");
}
@Override
public Set<QName> getHeaders() {
System.out.println("Server : getHeaders()......");
return null;
}
}
使用 SOAPHandler 处理请求后,请求如下所示:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<enns1:getMachine xmlns:enns1="http://machine.soap.webservices.product.company.at/">
<machineId xmlns="http://machine.soap.webservices.product.company.at/">92623-15853588</machineId>
</enns1:getMachine>
</S:Body>
</S:Envelope>
如您所见,我可以将命名空间前缀添加到<getMachine>
标签,但随后它会自动将xmlns
属性添加到子元素<machineId>
。我怎样才能避免或解决这个问题?