我正在将视觉foxpro应用程序转换为java Web应用程序,并且应用程序中的一个小但重要的部分向Web服务发出soap请求。
我已经编写了3个测试客户端来调用这个Web服务,我也通过SOAP UI进行了测试。我对此Web服务的每个测试都返回错误:java.net.SocketException:Connection reset。所以我显然在每种测试方法中都缺少同样的东西,或者做同样的事情。
我有foxpro代码,我已经通过foxpro成功提交了请求并收到了有效的回复。但是我对Foxpro没有任何经验,所以我一直在努力解决foxpro中的代码与我在java中编写的新代码之间的区别。
我希望有更多Soap和Web服务经验的人可以看到我的代码,也许自己尝试一下,并帮助我理解问题所在。
我将提供网络服务网址以及我的所有代码。我还将提供有效的foxpro命令行代码。
foxpro代码使用CreateObject("Microsoft.XMLHTTP")
。我通过研究了解到,这也用于ASP,VB.net和C#。
1)以下是我需要调用的Web服务:
主持人:https://rlisapi.myfwc.com/
肥皂终点:https://rlisapi.myfwc.com/wsReceipts.asmx
WSDL:https://rlisapi.myfwc.com/wsReceipts.asmx?WSDL
此Web服务不包含ws-security。凭据位于请求本身中。当然,我不能提供这些,但我不相信他们需要帮助我解决连接重置问题。
2)我创建的第一个客户端使用了SAAJ API。这是我的代码:
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 UI提交各种请求。有趣的是,我无法从URL加载wsdl,因此我将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)
在过去几天的所有研究中,我确定的是,此错误通常是由服务器在客户端完成读取之前关闭连接引起的。
起初我认为Web服务本身有问题,但由于我能够运行foxpro命令并获得有效的响应,但事实并非如此。
我也尝试更改Soap UI设置中的许多首选项,包括套接字超时。
此外,我的请求不通过代理服务器。
任何建议或建议将不胜感激! 谢谢。
更新后的帖子
以下是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,服务器Hello,握手协议证书,服务器Hello Done,客户端密钥交换,Change Cipher Spec,加密握手消息,最后是服务器的连接重置(RST)。
我查看了最后一帧上的专家信息意味着什么,看起来它可能意味着协议序列可疑,例如序列不连续或检测到重传......
这仍然让我挠头!我不明白我在我的代码中做了什么,或者从Soap UI中可能导致从服务器重置此连接。为什么它不会发生在foxpro代码中的Microsoft.XMLHTTP帖子中......难道我的请求是作为片段发送的,服务器不会接受吗?
我想我会尝试在运行foxpro命令时运行wireshark捕获,但这是在装有Windows 8的PC上,所以我需要先了解如何在admin下运行它。我运行的java测试客户端在我的mac上运行了连接重置。
与此同时,有没有人有进一步的见解?
答案 0 :(得分:9)
正如我所看到的,您的所有示例都应该正常运行。
我建议您使用一些数据包跟踪软件,如wireshark或fiddler,并检查请求/响应标头。也许在请求OutputStream之前需要在连接上设置一些额外的信息(UserAgent等)
================更新======================
如您所指定,服务器要求您启用SSLv3。 在建立连接之前使用它
System.setProperty("https.protocols", "SSLv3");
我在测试中做到了这一点,似乎连接因为我可以将soap消息写入OutputStream,但是我从服务器得到了500错误,这是一件好事,因为那是一个werbservice内部错误
现在您需要找到soap消息或消息数据
中的错误================更新2 ======================
固定!
澄清一下,我正在使用测试编号4 (HttpUrlConnection
)
消息第3行末尾缺少空格
"<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>