Почему я получаю сообщение java.net.SocketException: Connection reset от веб-службы через пользовательский интерфейс SOAP и клиент Java?

Я преобразовываю визуальное приложение foxpro в веб-приложение java, и одна небольшая, но важная часть приложения делает запрос на мыло к веб-службе.

Я написал 3 тестовых клиента для вызова этого веб-сервиса, и я также тестировал его через интерфейс SOAP. Каждый из моих тестов для этой веб-службы возвращает ошибку: java.net.SocketException: Connection reset. Поэтому я, очевидно, пропустил одно и то же в каждом методе тестирования или сделал то же самое неправильно.

У меня есть код foxpro, и я успешно отправил запрос через foxpro и получил действительный ответ. Но у меня нет опыта работы с Foxpro, поэтому я борюсь с разницей между кодом в foxpro, который работает, и новым кодом, который я пишу в java.

Я надеюсь, что кто-то, у кого больше опыта работы с Soap и веб-сервисами, сможет увидеть мой код, возможно, попробовать его сами, и помочь мне понять, в чем проблема.

Я предоставил URL-адрес веб-службы, а также весь мой код. Я также предоставил код командной строки foxpro, который работает.

В коде foxpro используется CreateObject("Microsoft.XMLHTTP"). В ходе моих исследований я узнал, что это также используется в ASP, VB.net и С#.

1) Вот веб-служба, которую мне нужно вызвать:

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

Конечная точка мыла: https://rlisapi.myfwc.com/wsReceipts.asmx

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

Этот веб-сервис не содержит ws-security. Учетные данные находятся в самом запросе. Конечно, я не могу предоставить их, но я не думаю, что они необходимы, чтобы помочь мне решить проблему соединения reset.

2) Первый клиент, который я создал, использовал API SAAJ. Вот мой код:

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) Следующая версия моего клиента использует Socket и 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) У меня есть аналогичный тестовый клиент, который использует 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... 
                } 

            }   
        }
    }
}

Наконец, помимо всех этих тестовых клиентов, я также попытался представить различные запросы с использованием интерфейса SOAP. Интересно, что я не мог загрузить wsdl из URL-адреса, поэтому я сохранил исходный код wsdl в локальном файле и использовал его.

Вот запрос, созданный Soap UI из файла 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 сохранен локально:

<?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>

Я также предоставил вам код Foxpro, который работает:

*******************************************
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)

Вот полный стек ошибки:

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)

Из всех моих исследований за последние пару дней, я определил, что эта ошибка чаще всего вызвана тем, что сервер закрывает соединение, прежде чем клиент будет читать его.

Сначала я подумал, что что-то не так с веб-сервисом, но поскольку я могу запустить команду foxpro и получить действительный ответ, это не может быть так.

Я также попытался изменить многие настройки в настройках пользовательского интерфейса Soap, включая тайм-аут сокета.

Кроме того, мои запросы не проходят через прокси-сервер.

Любые предложения или советы будут очень благодарны! Спасибо.


ОБНОВЛЕНО ПОСЛЕ ПОСЛЕДУЮЩИХ


Вот захват из Wireshark, простые ACK не указаны.

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

Затем повторяется серия сообщений.

Итак, я думаю, что это показывает, что сначала был сделан запрос на соединение от клиента, который был подтвержден сервером. Затем появился клиент Hello, сертификат сервера, сертификат протокола Handshake, сервер Hello Done, клиентский ключ Exchange, Change Cipher Spec, зашифрованное сообщение подтверждения, а затем, наконец, соединение reset (RST) с сервера.

Я посмотрел, что означает Expert Info на последнем кадре, и похоже, что это может означать подозрительность последовательности протоколов, например. последовательность не была непрерывной или была обнаружена повторная передача...

Это все еще заставляет меня почесывать голову! Я не понимаю, что я могу делать в своем коде, или из пользовательского интерфейса Soap, который может вызвать это соединение reset с сервера. И почему это не происходит из сообщения Microsoft.XMLHTTP в коде foxpro... Может ли быть, что мой запрос отправляется как фрагменты, и сервер не примет этого?

Я думаю, что я попытаюсь запустить захват wirehark при запуске команды foxpro, но это на ПК с Windows 8, поэтому мне нужно сначала выяснить, как запустить его под admin. Я запускаю тестовый клиент java, который получает соединение reset, на моем mac.

В то же время, есть ли у кого-нибудь более глубокое понимание?

Ответ 1

Как я вижу, все ваши примеры должны работать должным образом.

Я рекомендую вам использовать какое-то программное обеспечение трассировки пакетов, например wirehark или fiddler, и проверить заголовки запроса/ответа. Возможно, есть дополнительная информация (UserAgent и т.д.), Которые необходимо установить для соединения, прежде чем запрашивать OutputStream

================ ОБНОВЛЕНИЕ ======================

Как вы указали, сервер требует, чтобы вы включили SSLv3. Используйте это, прежде чем устанавливать соединение

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

Я сделал это в своем тесте и, похоже, подключился, так как я мог написать сообщение о мыле в OutputStream, но у меня получилось 500 ошибок с сервера, что хорошо, поскольку это внутренняя ошибка werbservice

Теперь вам нужно найти, что не так в сообщении с мылом, или данные сообщения

================ ОБНОВЛЕНИЕ 2 ======================

Фиксированный!

Чтобы уточнить, я использую номер теста 4 (HttpUrlConnection)

Нет недостающего места в конце третьей строки сообщения

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

должен быть

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

причина становится конкатенацией с определением xmlns:xsd.

Я получил этот ответ

<?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>