2016-08-12 42 views
6

我在java中創建了一個Soap客戶端,並且出現了一個奇怪的錯誤。SOAPExceptionImpl錯誤響應:404Not未找到,如果我不做soapMessage.writeTo(System.out);

摘要客戶

public abstract class AbstractSoapClient { 

    private ServerContext context; 

    private String path; 

    private static final String WSSE = ""; 
    private static final String CURL = ""; 
    private static final String CURL_PASSWORD = ""; 
    private static final String SECURITY_NODE = ""; 
    private static final String USERNAME_TOKEN = ""; 
    private static final String USERNAME_NODE = ""; 
    private static final String PASSWORD_NODE = ""; 

    public AbstractSoapClient(ServerContext context) { 
     this.context = context; 
    } 

    protected SOAPMessage createRequest(String path) throws SOAPException { 
     this.path = assembleEndpoint(path); 
     SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); 
     SOAPConnection soapConnection = soapConnectionFactory.createConnection(); 
     SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), this.path); 
     soapConnection.close(); 
     return soapResponse; 
    } 

    protected void setCredentials(SOAPEnvelope envelope) throws SOAPException { 
     SOAPHeader tHeader = envelope.getHeader(); 
     Name tWsseHeaderName = envelope.createName(SECURITY_NODE, WSSE, CURL); 

     SOAPHeaderElement tSecurityElement = tHeader.addHeaderElement(tWsseHeaderName); 
     tSecurityElement.setMustUnderstand(false); 

     Name tUserTokenElementName = envelope.createName(USERNAME_TOKEN, WSSE, CURL); 
     SOAPElement tUserTokenElement = tSecurityElement.addChildElement(tUserTokenElementName); 
     tUserTokenElement.removeNamespaceDeclaration(WSSE); 
     tUserTokenElement.addNamespaceDeclaration("wsu", CURL); 
     // user name child 
     Name tUsernameElementName = envelope.createName(USERNAME_NODE, WSSE, CURL); 
     SOAPElement tUsernameElement = tUserTokenElement.addChildElement(tUsernameElementName); 
     tUsernameElement.removeNamespaceDeclaration(WSSE); 
     tUsernameElement.addTextNode(context.getUsername()); 

     // password child 
     Name tPasswordElementName = envelope.createName(PASSWORD_NODE, WSSE, CURL); 
     SOAPElement tPasswordElement = tUserTokenElement.addChildElement(tPasswordElementName); 
     tPasswordElement.removeNamespaceDeclaration(WSSE); 
     tPasswordElement.setAttribute("Type", CURL_PASSWORD); 
     tPasswordElement.addTextNode(context.getPassword()); 
    } 

    private String assembleEndpoint(String path) { 
     return context.getUrl().concat(path); 
    } 

    protected abstract SOAPMessage createSOAPRequest() throws SOAPException; 

    public ServerContext getContext() { 
     return context; 
    } 

    public String getPath() { 
     return path; 
    } 

} 

SOAP客戶端執行

public class SoapClient extends AbstractSoapClient { 

    public SoapClient(ServerContext context) { 
     super(context); 
    } 

    @Override 
    public SOAPMessage createSOAPRequest() throws SOAPException { 
     MessageFactory messageFactory = MessageFactory.newInstance(); 
     SOAPMessage soapMessage = messageFactory.createMessage(); 
     SOAPPart soapPart = soapMessage.getSOAPPart(); 
     SOAPEnvelope envelope = soapPart.getEnvelope(); 
     setCredentials(envelope); 
     buildBody(envelope); 
     soapMessage.saveChanges(); 
     try { 
      soapMessage.writeTo(System.out); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return soapMessage; 
    } 

    private void buildBody(SOAPEnvelope envelope) throws SOAPException { 
     envelope.addNamespaceDeclaration("sch", "------"); 
     SOAPBody soapBody = envelope.getBody(); 
     SOAPElement soapBodyElem = soapBody.addChildElement("sampleData", "sampleData"); 
     SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem1.addTextNode("sampleData"); 
     SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem2.addTextNode("sampleData"); 
     SOAPElement soapBodyElem3 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem3.addTextNode("Y"); 
     SOAPElement soapBodyElem4 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem4.addTextNode("sampleData"); 
     SOAPElement soapBodyElem5 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem5.addTextNode("sampleData"); 
     SOAPElement soapBodyElem6 = soapBodyElem.addChildElement("sampleData"); 
     soapBodyElem6.addTextNode("sampleData"); 
    } 

    public static void main(String[] args) throws SOAPException, IOException { 
     SoapClient client = new SoapClient(
       new ServerContext("url", "user", "password")); 
     SOAPMessage response = client.createRequest("endpoint"); 
     response.writeTo(System.out); 
    } 

} 

奇怪的一點是在這部分代碼:

try { 
       soapMessage.writeTo(System.out); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

如果我COMM耳鼻喉科這個代碼,只打印請求之前發送它,我得到一個異常:

ago 12, 2016 12:58:17 PM com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection post 
    GRAVE: SAAJ0008: respuesta errónea; Not Found 
    Exception in thread "main" com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (404Not Found 
     at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:149) 
     at 
AbstractSoapClient.createRequest(AbstractSoapClient.java:44) 
     at SoapClient.main(SoapClient.java:67) 
    Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (404Not Found 
     at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:264) 
     at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:145) 
     ... 2 more 

    CAUSE: 

    com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (404Not Found 
     at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:264) 
     at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:145) 
     at AbstractSoapClient.createRequest(AbstractSoapClient.java:44) 
     at SoapClient.main(SoapClient.java:67) 

,但如果我不評論這條線,我可以得到正確的響應,對我來說這是沒有意義的,因爲爲什麼它發送一個404未找到如果我在發送它之前沒有在控制檯中寫入請求。

回答

1

如果您檢查writeTo implementation,您會看到它們添加了一個SOAPAction標頭。

嘗試以下操作:

MessageFactory messageFactory = MessageFactory.newInstance(); 
SOAPMessage soapMessage = messageFactory.createMessage(); 
soapMessage.getMimeHeaders().addHeader("SOAPAction", "\"\""); 

希望它能幫助。

+0

但是,爲什麼一個的writeTo方法,只有打印流中的請求頭添加到消息,真的是一個很好的做法? –

+0

我知道這聽起來很奇怪,而且肯定不是一個好習慣,但MessageImpl.writeTo源代碼可以做到這一點。 – fernandospr

0

默認情況下,SOAPMessage接口由SoapMessageImpl實現。 如果SOAPAction頭不存在,此實現具有添加SOAPAction頭的副作用。

打電話來的writeTo後,您可以通過調用其刪除:

soapMessage.getMimeHeaders().removeHeader("SOAPAction"); 

說了這麼多,而不是添加額外的代碼只記錄的調用和響應,我建議使用代理來代替。

如果你正在使用Eclipse,看看在TCP/Monitor View

相關問題