为什么我通过SOAP UI和java客户端从web服务接收到java.net.SocketException:Connection reset错误?
我正在将一个visualfoxpro应用程序转换为javaweb应用程序,该应用程序的一个小而重要的部分向web服务发出soap请求 我已经编写了3个测试客户机来调用这个web服务,并且还通过SOAP UI进行了测试。我对此web服务的每一个测试都返回错误:java.net.SocketException:Connection reset。所以很明显,我在每一种测试方法中都遗漏了同样的东西,或者做了同样的错误 我有foxpro代码,我已通过foxpro成功提交请求并收到有效响应。但是我对Foxpro没有任何经验,所以我一直在努力解决Foxpro中的代码与我用java编写的新代码之间的差异 我希望在Soap和web服务方面有更多经验的人能够看到我的代码,也许自己可以尝试一下,并帮助我了解问题所在 我将提供web服务url以及我的所有代码。我还将提供有效的foxpro命令行代码 foxpro代码使用为什么我通过SOAP UI和java客户端从web服务接收到java.net.SocketException:Connection reset错误?,java,web-services,soap,soapui,Java,Web Services,Soap,Soapui,我正在将一个visualfoxpro应用程序转换为javaweb应用程序,该应用程序的一个小而重要的部分向web服务发出soap请求 我已经编写了3个测试客户机来调用这个web服务,并且还通过SOAP UI进行了测试。我对此web服务的每一个测试都返回错误:java.net.SocketException:Connection reset。所以很明显,我在每一种测试方法中都遗漏了同样的东西,或者做了同样的错误 我有foxpro代码,我已通过foxpro成功提交请求并收到有效响应。但是我对Foxp
CreateObject(“Microsoft.XMLHTTP”)
。我通过研究了解到,ASP、VB.net和C#中也使用了这种方法
1) 以下是我需要调用的web服务:
主持人:https://rlisapi.myfwc.com/
Soap端点:https://rlisapi.myfwc.com/wsReceipts.asmx
WSDL:https://rlisapi.myfwc.com/wsReceipts.asmx?WSDL
此web服务不包含ws-security。凭据位于请求本身中。当然,我不能提供这些,但我不认为需要它们来帮助我解决连接重置问题
2) 我创建的第一个客户端使用SAAJAPI。这是我的密码:
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);
}
}
根据我过去几天的所有研究,我确定这个错误最常见的原因是服务器在客户端读取之前关闭了连接
起初我认为web服务本身有问题,但由于我能够运行foxpro命令并获得有效响应,所以情况就不可能如此了
我还尝试更改soapui设置中的许多首选项,包括套接字超时
此外,我的请求不通过代理服务器
如有任何建议,我们将不胜感激!
多谢各位
更新帖子如下
这是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、客户端密钥交换、更改密码规范、加密握手消息,最后是来自服务器的连接重置(RST)
我查看了最后一帧上的专家信息的含义,它可能意味着协议序列可疑,例如序列不连续或检测到重新传输
这仍然让我挠头!我不明白我可能在代码中做了什么,或者在Soap用户界面中做了什么,这可能会导致服务器重置连接。为什么在foxpro代码中的Microsoft.XMLHTTP帖子中没有出现这种情况。。。可能是我的请求被作为片段发送,而服务器不接受吗
我想我会尝试在运行foxpro命令时运行wireshark捕获,但这是在Windows 8的PC上进行的,所以我需要首先弄清楚如何在admin下运行它。我正在运行的java测试客户机在我的mac上进行连接重置
同时,有人有进一步的见解吗?如我所见,您的所有示例都应该正常工作 我建议您使用一些包跟踪软件,如wireshark或fiddler,并检查请求/响应头。在请求OutputStream之前,可能需要在连接上设置一些额外的信息(UserAgent等) ===================更新====================== 正如您所指定的,服务器要求您启用SSLv3。 在建立连接之前使用此选项
System.setProperty("https.protocols", "SSLv3");
我在测试中做到了这一点,它似乎是连接的,因为我可以将soap消息写入OutputStream,但我从服务器得到了一个500错误,这是一件好事,因为这是werbservice的内部故障
现在,您需要找出soap消息或消息数据中的错误
===================更新2======================
修正
为了澄清,我正在使用测试编号4(HttpUrlConnection
)
消息第三行末尾缺少空格
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
谢谢你的建议。我已经安装了wireshark,我正在尽力理解每个数据包跟踪都在说些什么。也许你或者比我更有嗅探数据包经验的人可以提供一些见解。此外,我之前确实与我的客户核实了请求中是否需要任何其他用户凭据,他告诉我没有。我的客户不是web服务的所有者,而是负责转换为java web应用程序的fox pro客户机的原始作者。我正在将wireshark中的跟踪行项目添加到上面的帖子中。我感谢你的帮助!我已经使用了你的代码,看起来还可以,我可以重现这个问题。可能服务器端(webservice)存在一些客户端验证,因为SSL连接正常,但被重置,可能是因为Web服务器无法识别客户端?在运行foxpro客户端时,我从pc上运行了跟踪。一个明显的区别是,在最初的客户机Hello消息中,从客户机到服务器的协议是sslv3,而在我的java客户机中,协议是sslv2,然后所有其他消息都通过sslv3发送。我赢了
<?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>
*******************************************
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)
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
System.setProperty("https.protocols", "SSLv3");
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
<?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>