2016-08-12 26 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

相关问题