2013-07-03 8 views
11

Sto convertendo un'applicazione visiva foxpro in un'applicazione web java e una piccola, ma importante parte dell'applicazione fa una richiesta di sapone a un servizio web.Perché ricevo un java.net.SocketException: errore di reimpostazione della connessione dal servizio Web tramite l'interfaccia utente SOAP e il client Java?

Ho scritto 3 client di prova per chiamare questo servizio Web e ho anche testato tramite interfaccia utente SOAP. Ognuno dei miei test su questo servizio Web restituisce l'errore: java.net.SocketException: Connection reset. Quindi, ovviamente, mi manca la stessa cosa in ogni metodo di test, o facendo la stessa cosa sbagliata.

Ho il codice foxpro e ho inviato correttamente la richiesta tramite foxpro e ho ricevuto una risposta valida. Ma non ho alcuna esperienza con Foxpro, quindi sono stato alle prese con la differenza tra il codice in foxpro che funziona e il nuovo codice che sto scrivendo in Java.

Spero che qualcuno con più esperienza con Soap e servizi Web possa vedere il mio codice, magari provarlo da solo e aiutarmi a capire qual è il problema.

Fornirò l'URL del servizio Web e tutto il mio codice. Fornirò anche il codice della riga di comando foxpro che funziona.

Il codice foxpro utilizza CreateObject("Microsoft.XMLHTTP"). Ho imparato attraverso la mia ricerca che questo è usato anche in ASP, VB.net e C#.

1) Qui è il servizio web che ho bisogno di chiamare:

Host: https://rlisapi.myfwc.com/

Sapone Endpoint: https://rlisapi.myfwc.com/wsReceipts.asmx

WSDL: https://rlisapi.myfwc.com/wsReceipts.asmx?WSDL

Questo servizio web non contiene WS-Security. Le credenziali sono nella richiesta stessa. Naturalmente non posso fornirle, ma non credo che siano necessarie per aiutarmi a risolvere il problema di reset della connessione.

2) Primo client che ho creato API SAAJ utilizzata. Qui è il mio codice:

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 

import javax.xml.soap.MessageFactory; 
import javax.xml.soap.Name; 
import javax.xml.soap.SOAPBody; 
import javax.xml.soap.SOAPBodyElement; 
import javax.xml.soap.SOAPConnection; 
import javax.xml.soap.SOAPConnectionFactory; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.SOAPPart; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 

import org.apache.log4j.Logger; 

import com.mycompany.webapp.domain.transaction.BusinessEntityTransaction; 
import com.mycompany.webapp.domain.transaction.ccars.PaymentCart; 
import com.mycompany.webapp.domain.transaction.rlis.RlisTransaction; 

public class RlisService { 
    private static Logger logger = Logger.getLogger("com.companyxyz.webapp.service.transaction.RlisService"); 

    public List<BusinessEntityTransaction> getCurrentTransactions(PaymentCart paymentCart) { 
     List<BusinessEntityTransaction> transactionList = new ArrayList<BusinessEntityTransaction>(); 
     List<RlisTransaction> rlisList = new ArrayList<RlisTransaction>(); 
     try { 
      logger.info("Adding current transactions from RLIS system..."); 
      rlisList = this.getCurrentTransactionsViaSoapRequest(); 

      for (RlisTransaction tx : rlisList){ 
       //add transaction received from web service to transactionList 
      } 

     } catch (UnsupportedOperationException e) { 
      e.printStackTrace(); 
     } catch (SOAPException e) { 
      e.printStackTrace(); 
     } 
     // do something with the rlisList - the list of RlisTransactions 
     return transactionList; 
    } 

    private List<RlisTransaction> getCurrentTransactionsViaSoapRequest() 
      throws UnsupportedOperationException, SOAPException { 
     List<RlisTransaction> rlisTransactions = new ArrayList<RlisTransaction>(); 
     // Create SOAP Connection 
     try { 
      SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); 
      SOAPConnection soapConnection = soapConnectionFactory.createConnection(); 

      // Send SOAP Message to SOAP Server 
      String url = "https://rlisapi.myfwc.com/wsReceipts.asmx"; 
      SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url); 

      // Process the SOAP Response 

      printSOAPResponse(soapResponse); 

      soapConnection.close(); 
     } catch (TransformerException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return rlisTransactions; 
    } 


    private static SOAPMessage createSOAPRequest() throws SOAPException, IOException { 
     MessageFactory messageFactory = MessageFactory.newInstance(); 
     SOAPMessage soapMessage = messageFactory.createMessage(); 
     SOAPPart soapPart = soapMessage.getSOAPPart(); 

     //String serverURI = "http://rlisapi.outdoorlicensesolution.com/"; 

     // SOAP Envelope 
     SOAPEnvelope envelope = soapPart.getEnvelope(); 
     //envelope.addNamespaceDeclaration("http://api.outdoorlicensesolution.com/RLIS/", serverURI); 

     // SOAP Body 
     SOAPBody soapBody = envelope.getBody(); 
     Name bodyName = envelope.createName("getDailyReceipts", "rlis", "http://api.outdoorlicensesolution.com/RLIS/"); 
     SOAPBodyElement getDailyReceiptsElement = soapBody.addBodyElement(bodyName); 

    //Name contentLenghName = envelope.createName("Content-Length"); 
     Name consumerPinName = envelope.createName("ConsumerPIN"); 
     Name agentIdName = envelope.createName("AgentID"); 
     Name receiptDateName = envelope.createName("ReceiptDate"); 

     //SOAPElement contentLengthElement = getDailyReceiptsElement.addChildElement(contentLenghName);   
     //contentLengthElement.addTextNode("494"); 

     SOAPElement consumerPinElement = getDailyReceiptsElement.addChildElement(consumerPinName); 
     consumerPinElement.addTextNode("my-consumer-pin"); 

     SOAPElement agentIdElement = getDailyReceiptsElement.addChildElement(agentIdName); 
     agentIdElement.addTextNode("000"); //not a real agent id 

     SOAPElement receiptDateElement = getDailyReceiptsElement.addChildElement(receiptDateName); 
     receiptDateElement.addTextNode("2013-07-01T00:00:00"); 



/* 
//this is the soap request string from foxpro: 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> 
<soap:Body> 
<getDailyReceipts xmlns="http://api.outdoorlicensesolution.com/RLIS/"> 
<Content-Length>494</Content-Length> 
<ConsumerPIN>APIKEY</ConsumerPIN> 
<AgentID>AGENTID</AgentID> 
<ReceiptDate>SALEDATE</ReceiptDate> 
</getDailyReceipts> 
</soap:Body> 
</soap:Envelope> 

*/ 
     soapMessage.saveChanges(); 

     /* Print the request message */ 
     System.out.print("Request SOAP Message = "); 
     soapMessage.writeTo(System.out); 
     System.out.println(); 

     return soapMessage; 
    } 

    private static void printSOAPResponse(SOAPMessage soapResponse) throws TransformerException, SOAPException { 
     logger.debug(soapResponse.getSOAPBody()); 
     TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
     Transformer transformer = transformerFactory.newTransformer(); 
     Source sourceContent = soapResponse.getSOAPPart().getContent(); 
     logger.debug("\nResponse SOAP Message = "); 
     System.out.print("\nResponse SOAP Message = "); 
     StreamResult result = new StreamResult(System.out); 
     transformer.transform(sourceContent, result); 

    } 

} 

(3) La prossima versione del mio cliente utilizza Socket e OutputStreamWriter

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 

import javax.xml.soap.MessageFactory; 
import javax.xml.soap.Name; 
import javax.xml.soap.SOAPBody; 
import javax.xml.soap.SOAPBodyElement; 
import javax.xml.soap.SOAPConnection; 
import javax.xml.soap.SOAPConnectionFactory; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.SOAPPart; 
import javax.xml.transform.Source; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerException; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.stream.StreamResult; 

import org.apache.log4j.Logger; 

import com.mycompany.webapp.domain.transaction.BusinessEntityTransaction; 
import com.mycompany.webapp.domain.transaction.ccars.PaymentCart; 
import com.mycompany.webapp.domain.transaction.rlis.RlisTransaction; 

public class RlisService { 
    private static Logger logger = Logger.getLogger("com.companyxyz.webapp.service.transaction.RlisService"); 

    public List<BusinessEntityTransaction> getCurrentTransactions(PaymentCart paymentCart) { 
     List<BusinessEntityTransaction> transactionList = new ArrayList<BusinessEntityTransaction>(); 
     List<RlisTransaction> rlisList = new ArrayList<RlisTransaction>(); 
     try { 
      logger.info("Adding current transactions from RLIS system..."); 
      rlisList = this.getCurrentTransactionsViaXmlHttp();   
      for (RlisTransaction tx : rlisList){ 
       //add transaction received from web service to transactionList 
      } 

     } catch (UnsupportedOperationException e) { 
      e.printStackTrace(); 
     } 
     // do something with the rlisList 
     return transactionList; 
    } 

    private List<RlisTransaction> getCurrentTransactionsViaXmlHttp(){ 
     List<RlisTransaction> rlisTransactions = new ArrayList<RlisTransaction>(); 

     String xmldata = "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + 
     "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + 
     "xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" + 
     "<soap:Body>" + 
     "<getDailyReceipts xmlns=\"http://api.outdoorlicensesolution.com/RLIS/\">" + 
     //"<Content-Length>494</Content-Length>" + 
     "<ConsumerPIN>APIKEY</ConsumerPIN>" + 
     "<AgentID>AGENTID</AgentID>" + 
     "<ReceiptDate>SALEDATE</ReceiptDate>" + 
     "</getDailyReceipts>" + 
     "</soap:Body>" + 
     "</soap:Envelope>"; 

     try{ 

      //Create socket 
      String hostname = "rlisapi.myfwc.com"; 
      int port = 443; 
      InetAddress addr = InetAddress.getByName(hostname); 
      Socket sock = new Socket(addr, port); 
      //Socket sock = new Socket(hostname, port); 

      //Send header 
      String path = "https://rlisapi.myfwc.com/wsReceipts.asmx"; 
      BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream(),"UTF-8")); 
      // You can use "UTF8" for compatibility with the Microsoft virtual machine. 
      wr.write("POST " + path + " HTTP/1.0\r\n"); 
      wr.write("Host: rlisapi.myfwc.com\r\n"); 
      wr.write("Content-Length: " + xmldata.length() + "\r\n"); 
      wr.write("Content-Type: text/xml; charset=\"utf-8\"\r\n"); 
      wr.write("\r\n"); 

      //Send data 
      wr.write(xmldata); 
      wr.flush(); 

      // Response 
      BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream())); 
      String line; 
      while((line = rd.readLine()) != null) 
      System.out.println(line); 

     } catch (Exception e) { 
       e.printStackTrace(); 
     } 

     return rlisTransactions; 
    } 

} 

(4) Ho un client di prova simile che utilizza HttpURLConnection

import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.net.URLConnection; 

public class TestXmlClient { 

    public static void main(String[] args) { 
     String argUrl = "https://rlisapi.myfwc.com/wsReceipts.asmx"; 

     System.out.println("Test XML Client"); 

     String requestXml = 
       "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + 
       "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + 
       "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + 
       "xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" + 
       "<soap:Body>" + 
       "<getDailyReceipts xmlns=\"http://api.outdoorlicensesolution.com/RLIS/\">" + 
       "<Content-Length>494</Content-Length>" + 
       "<ConsumerPIN>my-consumer-pin</ConsumerPIN>" + 
       "<AgentID>000</AgentID>" + //not real agent id 
       "<ReceiptDate>2013-07-01T00:00:00</ReceiptDate>" + 
       "</getDailyReceipts>" + 
       "</soap:Body>" + 
       "</soap:Envelope>" ; 

     System.out.println("Request: " + requestXml); 

     //try { 
     URL url; 
     OutputStreamWriter writer = null; 
     InputStreamReader reader = null; 
     HttpURLConnection con = null; 

     try { 
      url = new URL (argUrl); 
     con = (HttpURLConnection) url.openConnection(); 

     URLConnection urlc = url.openConnection(); 
     HttpURLConnection httpc = (HttpURLConnection)urlc; 
     // only interested in the length of the resource 
     httpc.setRequestMethod("HEAD"); 
     int len = httpc.getContentLength(); 

     System.out.println("length: " + len); 

     // specify that we will send output and accept input 
     con.setDoInput(true); 
     con.setDoOutput(true); 

     con.setConnectTimeout(20000); // long timeout, but not infinite 
     con.setReadTimeout(20000); 

     con.setUseCaches (false); 
     con.setDefaultUseCaches (false); 

     // tell the web server what we are sending 
     //con.setRequestProperty ("Content-Type", "text/xml"); 
     con.setRequestProperty ("Content-Type", "text/xml; charset=utf-8"); 
     //con.setRequestProperty("Connection", "close"); 

     writer = new OutputStreamWriter(con.getOutputStream()); 

     writer.write(requestXml); 
     writer.flush(); 
     writer.close(); 

     // reading the response 
     reader = new InputStreamReader(con.getInputStream()); 
     StringBuilder buf = new StringBuilder(); 
     char[] cbuf = new char[ 2048 ]; 
     int num; 
     while (-1 != (num=reader.read(cbuf))) { 
      buf.append(cbuf, 0, num); 
     } 
     String result = buf.toString(); 
     System.err.println("\nResponse from server after POST:\n" + result); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      System.out.println(e.getStackTrace()); 
      e.printStackTrace(); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } finally{ 
      if (writer != null) { 
       try { 
        writer.close(); 
       } catch (Exception e) { 
        // ignore... 
       } 
      } 
      if (reader != null) { 
       try { 
        reader.close(); 
       } catch (Exception e) { 
        // ignore... 
       } 
      } 

      if (con != null) { 
       try { 
        con.disconnect(); 
       } catch (Exception e) { 
        // ignore... 
       } 

      } 
     } 
    } 
} 

Infine, oltre a tutti questi client di test, ho anche provato a inviare varie richieste utilizzando l'interfaccia utente SOAP. È interessante notare che non ho potuto caricare il wsdl dall'URL, quindi ho salvato il codice sorgente wsdl in un file locale e l'ho usato.

Ecco la richiesta generata dal Soap UI da file WSDL:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:rlis="http://api.outdoorlicensesolution.com/RLIS/"> 
    <soap:Header/> 
    <soap:Body> 
     <rlis:getDailyReceipts> 
     <!--Optional:--> 
     <rlis:ConsumerPIN>?</rlis:ConsumerPIN> 
     <rlis:AgentID>?</rlis:AgentID> 
     <rlis:ReceiptDate>?</rlis:ReceiptDate> 
     </rlis:getDailyReceipts> 
    </soap:Body> 
</soap:Envelope> 

WSDL salvato in locale:

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://api.outdoorlicensesolution.com/RLIS/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://api.outdoorlicensesolution.com/RLIS/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> 
    <wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://api.outdoorlicensesolution.com/RLIS/"> 
     <s:element name="getDailyReceipts"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="ConsumerPIN" type="s:string" /> 
      <s:element minOccurs="1" maxOccurs="1" name="AgentID" type="s:int" /> 
      <s:element minOccurs="1" maxOccurs="1" name="ReceiptDate" type="s:dateTime" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:element name="getDailyReceiptsResponse"> 
     <s:complexType> 
      <s:sequence> 
      <s:element minOccurs="0" maxOccurs="1" name="getDailyReceiptsResult" type="tns:ArrayOfReceipt" /> 
      </s:sequence> 
     </s:complexType> 
     </s:element> 
     <s:complexType name="ArrayOfReceipt"> 
     <s:sequence> 
      <s:element minOccurs="0" maxOccurs="unbounded" name="Receipt" nillable="true" type="tns:Receipt" /> 
     </s:sequence> 
     </s:complexType> 
     <s:complexType name="Receipt"> 
     <s:sequence> 
      <s:element minOccurs="1" maxOccurs="1" name="OrderID" type="s:int" /> 
      <s:element minOccurs="1" maxOccurs="1" name="TotalSaleAmount" type="s:decimal" /> 
      <s:element minOccurs="1" maxOccurs="1" name="TaxCollectorFees" type="s:decimal" /> 
      <s:element minOccurs="1" maxOccurs="1" name="OrderDate" type="s:dateTime" /> 
      <s:element minOccurs="0" maxOccurs="1" name="OrderStatus" type="s:string" /> 
      <s:element minOccurs="1" maxOccurs="1" name="AmountToACH" type="s:decimal" /> 
      <s:element minOccurs="1" maxOccurs="1" name="CustomerID" type="s:int" /> 
      <s:element minOccurs="0" maxOccurs="1" name="CustomerName" type="s:string" /> 
      <s:element minOccurs="0" maxOccurs="1" name="ClerkUserName" type="s:string" /> 
      <s:element minOccurs="0" maxOccurs="1" name="TarponTagBegin" type="s:string" /> 
      <s:element minOccurs="0" maxOccurs="1" name="TarponTagEnd" type="s:string" /> 
      <s:element minOccurs="0" maxOccurs="1" name="ErrorMessage" type="s:string" /> 
     </s:sequence> 
     </s:complexType> 
    </s:schema> 
    </wsdl:types> 
    <wsdl:message name="getDailyReceiptsSoapIn"> 
    <wsdl:part name="parameters" element="tns:getDailyReceipts" /> 
    </wsdl:message> 
    <wsdl:message name="getDailyReceiptsSoapOut"> 
    <wsdl:part name="parameters" element="tns:getDailyReceiptsResponse" /> 
    </wsdl:message> 
    <wsdl:portType name="wsReceiptsSoap"> 
    <wsdl:operation name="getDailyReceipts"> 
     <wsdl:input message="tns:getDailyReceiptsSoapIn" /> 
     <wsdl:output message="tns:getDailyReceiptsSoapOut" /> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="wsReceiptsSoap" type="tns:wsReceiptsSoap"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="getDailyReceipts"> 
     <soap:operation soapAction="http://api.outdoorlicensesolution.com/RLIS/getDailyReceipts" style="document" /> 
     <wsdl:input> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="wsReceiptsSoap12" type="tns:wsReceiptsSoap"> 
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="getDailyReceipts"> 
     <soap12:operation soapAction="http://api.outdoorlicensesolution.com/RLIS/getDailyReceipts" style="document" /> 
     <wsdl:input> 
     <soap12:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap12:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="wsReceipts"> 
    <wsdl:port name="wsReceiptsSoap" binding="tns:wsReceiptsSoap"> 
     <soap:address location="https://rlisapi.myfwc.com/wsReceipts.asmx" /> 
    </wsdl:port> 
    <wsdl:port name="wsReceiptsSoap12" binding="tns:wsReceiptsSoap12"> 
     <soap12:address location="https://rlisapi.myfwc.com/wsReceipts.asmx" /> 
    </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

farò anche fornire il codice di FoxPro che funziona:

******************************************* 
SALEDATE = DATE()-1 
XMLRESPONSE = '' 

M.AGENTID = '000' 
M.APIKEY = 'my-consumer-pin' 

M.cSALEDATE = STR(YEAR(SALEDATE),4) + '-' + PADL(ALLTRIM(STR(MONTH(SALEDATE),2)),2,'0') + '-' + PADL(ALLTRIM(STR(DAY(SALEDATE),2)),2,'0') + 'T00:00:00' 

TEXT TO XMLHTTP NOSHOW 
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> 
<soap:Body> 
<getDailyReceipts xmlns="http://api.outdoorlicensesolution.com/RLIS/"> 
<Content-Length>494</Content-Length> 
<ConsumerPIN>APIKEY</ConsumerPIN> 
<AgentID>AGENTID</AgentID> 
<ReceiptDate>SALEDATE</ReceiptDate> 
</getDailyReceipts> 
</soap:Body> 
</soap:Envelope> 
ENDTEXT 
XMLHTTP = STRTRAN(XMLHTTP,'APIKEY',M.APIKEY) 
XMLHTTP = STRTRAN(XMLHTTP,'AGENTID',M.AGENTID) 
XMLHTTP = STRTRAN(XMLHTTP,'SALEDATE',M.cSALEDATE) 



oHTTP = CreateObject("Microsoft.XMLHTTP") 
oHTTP.Open("POST", "https://rlisapi.myfwc.com/wsReceipts.asmx", .F.) 

oHTTP.setRequestHeader('Content-Type', 'text/xml; charset=utf-8 ') 
oHTTP.Send(XMLHTTP) 


DO CASE 
CASE oHTTP.status = 200 
       XMLRESPONSE = oHTTP.ResponseText 
       RELEASE oHTTP 
CASE oHTTP.status = 201 
       WAIT'PROCESSING PLEASE WAIT' WINDOW NOWAIT 
       RELEASE oHTTP 
CASE oHTTP.status = 202 
       WAIT 'PROCESSING PLEASE WAIT' WINDOW NOWAIT 
       RELEASE oHTTP 
CASE oHTTP.status = 400 
       RELEASE oHTTP 
       MESSAGEBOX("RLIS BAD REQUEST ERROR",0,'CCARS') 
       RETURN 
CASE oHTTP.status = 401 
       RELEASE oHTTP 
       MESSAGEBOX("RLIS UNAUTHORIZED ERROR",0,'CCARS') 
       RETURN 
CASE oHTTP.status = 403 
       RELEASE oHTTP 
       MESSAGEBOX("RLIS FORBIDDEN ERROR",0,'CCARS') 
       RETURN 
CASE oHTTP.status = 404 
       RELEASE oHTTP 
       MESSAGEBOX("CONNECTION TO RLIS SITE NOT AVAILABLE",0,'CCARS') 
       RETURN 
CASE oHTTP.status = 500 
       RELEASE oHTTP 
       MESSAGEBOX("RLIS INTERNAL SERVER ERROR",0,'CCARS') 
       RETURN 
OTHERWISE 
       RELEASE oHTTP 
       MESSAGEBOX(oHTTP.status,0,'CCARS') 
       MESSAGEBOX("RLIS INTERNAL SERVER ERROR CODE " + STR(oHTTP.status,3,0),0,'CCARS') 
       RETURN 
ENDCASE 

MESSAGEBOX(XMLRESPONSE) 

Ecco la piena StackTrace dell'errore:

java.net.SocketException: Connection reset 
at java.net.SocketInputStream.read(SocketInputStream.java:168) 
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:422) 
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:460) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:863) 
at  com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1215) 
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199) 
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434) 
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) 
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014) 
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) 
at com.taxcollector.ccars.service.transaction.TestSoapClient.main(TestSoapClient.java:51) 

Da tutta la mia ricerca nel corso degli ultimi due giorni, quello che ho deciso è che questo errore è spesso causato dal server di chiudere la connessione prima il cliente finito di leggerlo

All'inizio ho pensato che c'era qualcosa di sbagliato nel servizio web stesso, ma dal momento che sono in grado di eseguire il comando foxpro e ottenere una risposta valida, non può essere il caso.

Ho provato a modificare molte delle preferenze nelle impostazioni dell'interfaccia utente Soap, incluso il timeout del socket.

Inoltre, le mie richieste non passano attraverso un server proxy.

Qualsiasi suggerimento o consiglio sarà molto apprezzato! Grazie.


AGGIORNAMENTO POST SEGUE


Ecco la cattura da Wireshark, semplici ACK omessi.

4034 2013-07-05 10:34:04.556901000 192.168.0.106 162.209.25.202 SSLv2 178 Client Hello 
4038 2013-07-05 10:34:04.669714000 162.209.25.202 192.168.0.106 SSLv3 1386 Server Hello, Certificate, Server Hello Done 
4040 2013-07-05 10:34:04.880678000 192.168.0.106 162.209.25.202 SSLv3 331 Client Key Exchange 
4041 2013-07-05 10:34:04.885161000 192.168.0.106 162.209.25.202 SSLv3 72 Change Cipher Spec 
4042 2013-07-05 10:34:04.887886000 192.168.0.106 162.209.25.202 SSLv3 127 Encrypted Handshake Message 
4045 2013-07-05 10:34:05.142999000 162.209.25.202 192.168.0.106 TCP 54 https > 58365 [RST, ACK] Seq=2769 Ack=445 Win=4584 Len=0 

Quindi la serie di messaggi si ripete.

Quindi penso che ciò che sta dimostrando è che prima c'era una richiesta di connessione da parte del client, che è stata confermata dal server. Poi c'era un client Hello, un server Hello, un certificato di protocollo handshake, un server Hello Done, un client Key Exchange, Change Cipher Spec, un messaggio crittografato di handshake e infine il Connection Reset (RST) dal server.

Ho cercato cosa significa l'Expert Info sull'ultimo frame, e sembra che potrebbe significare sospetto sequenza di protocolli, ad es. la sequenza non era continua o è stata rilevata una ritrasmissione ...

Questo mi fa ancora grattarmi la testa! Non capisco cosa potrei fare nel mio codice o dall'interfaccia utente Soap che potrebbe causare il reset di questa connessione dal server. E perché non succede dal post Microsoft.XMLHTTP nel codice foxpro ... Potrebbe essere che la mia richiesta viene inviata come frammenti e il server non lo accetterà?

Penso che proverò a eseguire un'acquisizione di wireshark mentre eseguo il comando foxpro, ma quello è su un PC con Windows 8, quindi ho bisogno di capire prima come eseguirlo sotto admin. Il client di prova java che sto eseguendo che ottiene una reimpostazione della connessione è sul mio mac.

Nel frattempo, qualcuno ha ulteriori informazioni?

risposta

7

Come posso vedere, tutti gli esempi dovrebbero funzionare correttamente.

Ti consiglio di utilizzare un software di tracciamento pacchetti, come wireshark o Fiddler, e controllare le intestazioni richiesta/risposta. Forse c'è qualche informazione in più (AgenteUtente, ecc) che è necessario impostare per la connessione prima di richiedere l'OutputStream

================ UPDATE ====== ================

Come specificato, il server richiede di abilitare SSLv3. Utilizzare questa prima di stabilire la connessione

System.setProperty("https.protocols", "SSLv3"); 

ho fatto nel mio test, e sembrava di connettersi da quando ho potuto scrivere il messaggio SOAP al OutputStream, ma ho ricevuto una 500 Errore dal server, che è una buona cosa dal momento che è un guasto interno werbservice

Ora è necessario trovare ciò che è sbagliato nel messaggio sapone, o i dati del messaggio

UPDATE ================ 2 ======================

Riparato!

Per chiarire, sto usando il numero di test (HttpUrlConnection)

Theres uno spazio mancante alla fine del 3 ° riga del messaggio

"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + 

dovrebbe essere

"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + 

causa viene contatenato con la definizione xmlns:xsd.

ho avuto questa risposta

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soap:Body> 
     <getDailyReceiptsResponse xmlns="http://api.outdoorlicensesolution.com/RLIS/"> 
      <getDailyReceiptsResult> 
       <Receipt> 
        <OrderID>0</OrderID> 
        <TotalSaleAmount>0</TotalSaleAmount> 
        <TaxCollectorFees>0</TaxCollectorFees> 
        <OrderDate>0001-01-01T00:00:00</OrderDate> 
        <AmountToACH>0</AmountToACH> 
        <CustomerID>0</CustomerID> 
        <ErrorMessage>Invalid Logon Credentials</ErrorMessage> 
       </Receipt> 
      </getDailyReceiptsResult> 
     </getDailyReceiptsResponse> 
    </soap:Body> 
</soap:Envelope> 
+0

Grazie per il suggerimento. Ho installato wireshark e sto facendo del mio meglio per capire cosa sta dicendo ogni traccia di pacchetti. Forse tu o qualcuno con più esperienza di me con i pacchetti di sniffing è possibile fornire alcune informazioni. Inoltre, ho controllato in precedenza con il mio cliente se c'erano richieste di altre credenziali utente nella richiesta e lui mi ha detto di no. Il mio cliente non è il proprietario del servizio web, ma l'autore originale del client fox-pro che ho il compito di convertire in un'applicazione web java. Sto aggiungendo gli elementi di tracciamento da wireshark al mio post qui sopra. Apprezzo il vostro aiuto! –

+0

Ho usato il tuo codice, sembra OK, e posso riprodurre il problema. Forse c'è qualche verifica client sul lato server (webservice) perché la connessione SSL è OK, ma è stata ripristinata, forse perché il server web non riconosce il client ..? –

+1

Ho eseguito la traccia dal mio pc mentre eseguivo il client foxpro. L'unica differenza evidente era che il protocollo da client a server sul messaggio Client Hello iniziale era sslv3, mentre dal mio client java era sslv2, quindi tutti gli altri messaggi venivano inviati tramite sslv3. Mi chiedo se l'incoerenza fosse considerata sospetta dal server ... –