如何使用自定义SOAPHandler正确格式化SOAP消息信封

我有一个实现SOAPHandler接口的类 。 handleMessage定义为:

public boolean handleMessage(SOAPMessageContext context) { SOAPMessage msg = context.getMessage(); SOAPPart part = msg.getSOAPPart(); SOAPEnvelope envelope = part.getEnvelope(); // add namespaces SOAPElement envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema"); envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema- // add the header with additional elements Name qname = envelope.createName("Security", "sse", "http://example.com/security.xsd"); element = envelope.addHeader().addChildElement(qname); qname = envelope.createName("mustUnderstand"); element.addAttribute(qname, "1"); qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd"); element = envelope.getHeader().addHeaderElement(qname); element.addTextNode("user1"); qname = envelope.createName("Password"); element = envelope.getHeader().addHeaderElement(qname); element.addTextNode("1234"); } } catch (Exception e) { e.printStackTrace(); } return true; } 

这会生成以下消息:

    user1   ....The rest of the transaction   

问题是我需要生成一个格式如下的消息:

     user1 1234     ....The rest of the transaction   

“mustUnderstand”属性没有soapenv前缀,sse:Security标记立即关闭,而不是将其他标记作为子标记,并且UserName没有正确格式化为

 user1 

。 如何使用SOAPElement方法正确格式化消息? 我需要知道的最重要的事情是如何正确地下一步安全标签内的标签以及如何正确格式化用户名/密码标签。

我已经尝试了addHeaderElement和addChildElement方法的不同组合,但是我无法正确地对其进行格式化,并且javadocs没有提供关于它们将生成什么的足够详细信息。

这是从我的工作处理程序中获取的。 希望对你有效。

 public static final String WSSE_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; public static final String PASSWORD_TEXT_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; public static final String WSSE_SECURITY_LNAME = "Security"; public static final String WSSE_NS_PREFIX = "wsse"; private String username; private String password; private boolean mustUnderstand = false; public boolean handleMessage(SOAPMessageContext messageContext) { Object bOutbound = messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (bOutbound == Boolean.TRUE) { try { if (username != null && username.length() != 0) { addSecurityHeader(messageContext); LOG.debug("Added security header"); } else { LOG.debug("No username configured thus not adding a security header"); } } catch (Exception e) { LOG.error("Exception in handleMessage", e); return false; } } return true; } private void addSecurityHeader(SOAPMessageContext messageContext) throws SOAPException { SOAPFactory sf = SOAPFactory.newInstance(); SOAPHeader header = messageContext.getMessage().getSOAPPart().getEnvelope().getHeader(); if (header == null) { header = messageContext.getMessage().getSOAPPart().getEnvelope().addHeader(); } Name securityName = sf.createName(WSSE_SECURITY_LNAME, WSSE_NS_PREFIX, WSSE_NS); SOAPHeaderElement securityElem = header.addHeaderElement(securityName); securityElem.setMustUnderstand(mustUnderstand); Name usernameTokenName = sf.createName("UsernameToken", WSSE_NS_PREFIX, WSSE_NS); SOAPElement usernameTokenMsgElem = sf.createElement(usernameTokenName); Name usernameName = sf.createName("Username", WSSE_NS_PREFIX, WSSE_NS); SOAPElement usernameMsgElem = sf.createElement(usernameName); usernameMsgElem.addTextNode(username); usernameTokenMsgElem.addChildElement(usernameMsgElem); Name passwordName = sf.createName("Type", WSSE_NS_PREFIX, WSSE_NS); SOAPElement passwordMsgElem = sf.createElement("Password", WSSE_NS_PREFIX, WSSE_NS); passwordMsgElem.addAttribute(passwordName, PASSWORD_TEXT_TYPE); passwordMsgElem.addTextNode(password); usernameTokenMsgElem.addChildElement(passwordMsgElem); securityElem.addChildElement(usernameTokenMsgElem); } 

如果有人仍然想知道,只需发布​​我的解决方案 –

 Name name = soapenv.createName("Security", "sse", "URL"); SOAPHeaderElement security = soapenv.getHeader().addHeaderElement(name); security.setMustUnderstand(true); SOAPElement usernameToken = security.addChildElement("UsernameToken", "sse"); SOAPElement username = usernameToken.addChildElement("Username", "sse"); username.addTextNode("TestUser"); SOAPElement password = usernameToken.addChildElement("Password", "sse"); password.addTextNode("TestPassword"); 

在这段代码中有足够的问题,我认为这是一个巨魔,但他是一个开始:

这条线:

 element = envelope.addHeader().addChildElement(qname); 

应该读:

 SOAPHeaderElement secHdrElement = envelope.addHeader().addHeaderElement(qname); 

接下来,而不是:

 qname = envelope.createName("mustUnderstand"); element.addAttribute(qname, "1"); 

大概:

 secHdrElement.setMustUnderstand(true); 

 qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd"); element = envelope.getHeader().addHeaderElement(qname); element.addTextNode("user1"); 

应该是这样的:

 qname = envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd"); element = secHdrElement.addHeaderElement( envelope.createName("UsernameToken", "sse", "http://example.com/user.xsd")); 

等等…