2009-07-28 34 views
2

我有一個類實現了SOAPHandler interface。所述的handleMessage定義爲:如何使用自定義SOAPHandler正確格式化SOAP消息信封

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; 
} 

這產生以下消息:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <S:Header> 
    <sse:Security xmlns:sse="http://example.com/security.xsd" mustUnderstand="1"/> 
    <sse:UsernameToken xmlns:sse="http://example.com/user.xsd">user1</sse:UsernameToken> 
    </S:Header> 
    <S:Body> 
    ....The rest of the transaction 
    </S:Body> 
</S:Envelope> 

的問題是我需要生成具有下列格式的消息:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soapenv:Header> 
     <sse:Security soapenv:mustUnderstand="1" xmlns:sse="http://example.com/security.xsd"> 
     <sse:UsernameToken wsu:Id="UsernameToken-9993341" xmlns:wsu="http://example.com/user.xsd"> 
      <sse:Username>user1</sse:Username> 
      <sse:Password Type="http://example.com/password#PasswordText">1234</sse:Password> 
     </sse:UsernameToken> 
     </sse:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
    ....The rest of the transaction 
    </soapenv:Body> 
</soapenv:Envelope> 

的「的mustUnderstand 「屬性沒有soapenv前綴,sse:Security標籤立即關閉,而不是將其他標籤設置爲子項,並且UserName的格式不正確爲

<sse:Username>user1</sse:Username> 

。如何使用SOAPElement方法正確格式化消息?我需要知道的最重要的事情是如何正確地在安全標籤內部貼上標籤,以及如何正確格式化用戶名/密碼標籤。

我已經嘗試了addHeaderElement和addChildElement方法的不同組合,但我無法正確格式化它,並且javadocs沒有提供足夠的關於它們將生成的細節的詳細信息。

+0

是否有你有這個問題標記爲「C#」的理由? – 2009-07-29 00:01:12

+0

沒有 - 我一直在使用C#來處理大部分項目,並且默認情況下甚至沒有考慮它。感謝您更新的標籤。 – 2009-07-29 00:12:55

回答

-2

有這個代碼,我想這是一個巨魔足夠的問題,但繼承人一個開始:

行:

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")); 

等等...

6

這是從我的工作處理程序作出。希望對你有效。

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); 
} 
3

只是發表我的解決辦法,如果有人還在疑惑 -

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");