工作皂客户端示例

我试图找到一个简单的(哈) SOAP 例子在 JAVA 与工作服务,我似乎找不到任何工作。

我已经尝试了这个 从这个 例子,但它只是不工作,它要求我把一个向前斜杠,但它在那里,什么也没有发生。

那么是否有人知道任何 SOAP 示例链接,我可以下载/请求和乱搞?

谢谢你的帮助。

366644 次浏览

要在 Java 中实现简单的 SOAP 客户机,可以使用 SAAJ 框架(它是随 JSE 1.6及以上版本一起提供的,但在 Java 11中又被删除了) :

SAAJ (SAAJ) 主要用于直接处理发生在任何 Web 服务 API 幕后的 SOAP 请求/响应消息。它允许开发人员直接发送和接收肥皂消息,而不必使用 JAX-WS。

下面是一个使用 SAAJ 的 SOAPWeb 服务调用的工作示例(运行它!) ,它调用 网上服务

import javax.xml.soap.*;


public class SOAPClientSAAJ {


// SAAJ - SOAP Client Testing
public static void main(String args[]) {
/*
The example below requests from the Web Service at:
http://www.webservicex.net/uszip.asmx?op=GetInfoByCity




To call other WS, change the parameters below, which are:
- the SOAP Endpoint URL (that is, where the service is responding from)
- the SOAP Action


Also change the contents of the method createSoapEnvelope() in this class. It constructs
the inner part of the SOAP envelope that is actually sent.
*/
String soapEndpointUrl = "http://www.webservicex.net/uszip.asmx";
String soapAction = "http://www.webserviceX.NET/GetInfoByCity";


callSoapWebService(soapEndpointUrl, soapAction);
}


private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
SOAPPart soapPart = soapMessage.getSOAPPart();


String myNamespace = "myNamespace";
String myNamespaceURI = "http://www.webserviceX.NET";


// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);


/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="http://www.webserviceX.NET">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<myNamespace:GetInfoByCity>
<myNamespace:USCity>New York</myNamespace:USCity>
</myNamespace:GetInfoByCity>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/


// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("GetInfoByCity", myNamespace);
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("USCity", myNamespace);
soapBodyElem1.addTextNode("New York");
}


private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();


// Send SOAP Message to SOAP Server
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);


// Print the SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);
System.out.println();


soapConnection.close();
} catch (Exception e) {
System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
e.printStackTrace();
}
}


private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();


createSoapEnvelope(soapMessage);


MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", soapAction);


soapMessage.saveChanges();


/* Print the request message, just for debugging purposes */
System.out.println("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println("\n");


return soapMessage;
}


}

是的,如果您可以获取任何 WSDL 文件,那么您可以使用 SoapUI 来创建该服务的模拟服务,并完成单元测试请求。我 创建了一个示例(使用 Maven) ,您可以尝试使用

对于 WSDL 的基本身份验证,接受的应答代码将引发错误

Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username","password".toCharArray());
}
});
String send =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
"        <soap:Body>\n" +
"        </soap:Body>\n" +
"</soap:Envelope>";


private static String getResponse(String send) throws Exception {
String url = "https://api.comscore.com/KeyMeasures.asmx"; //endpoint
String result = "";
String username="user_name";
String password="pass_word";
String[] command = {"curl", "-u", username+":"+password ,"-X", "POST", "-H", "Content-Type: text/xml", "-d", send, url};
ProcessBuilder process = new ProcessBuilder(command);
Process p;
try {
p = process.start();
BufferedReader reader =  new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ( (line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
result = builder.toString();
}
catch (IOException e)
{   System.out.print("error");
e.printStackTrace();
}


return result;
}

AcdcJunior 的响应非常棒,我只是用下一段代码展开了他的解释,在这段代码中,您可以看到如何迭代 XML 元素。

public class SOAPClientSAAJ {


public static void main(String args[]) throws Exception {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();


// Send SOAP Message to SOAP Server
String url = "http://ws.cdyne.com/emailverify/Emailvernotestemail.asmx";
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url);






SOAPPart soapPart=soapResponse.getSOAPPart();
// SOAP Envelope
SOAPEnvelope envelope=soapPart.getEnvelope();
SOAPBody soapBody = envelope.getBody();


@SuppressWarnings("unchecked")
Iterator<Node> itr=soapBody.getChildElements();
while (itr.hasNext()) {


Node node=(Node)itr.next();
if (node.getNodeType()==Node.ELEMENT_NODE) {
System.out.println("reading Node.ELEMENT_NODE");
Element ele=(Element)node;
System.out.println("Body childs : "+ele.getLocalName());


switch (ele.getNodeName()) {


case "VerifyEmailResponse":
NodeList statusNodeList = ele.getChildNodes();


for(int i=0;i<statusNodeList.getLength();i++){
Element emailResult = (Element) statusNodeList.item(i);
System.out.println("VerifyEmailResponse childs : "+emailResult.getLocalName());
switch (emailResult.getNodeName()) {


case "VerifyEmailResult":
NodeList emailResultList = emailResult.getChildNodes();


for(int j=0;j<emailResultList.getLength();j++){
Element emailResponse = (Element) emailResultList.item(j);
System.out.println("VerifyEmailResult childs : "+emailResponse.getLocalName());
switch (emailResponse.getNodeName()) {
case "ResponseText":
System.out.println(emailResponse.getTextContent());
break;
case "ResponseCode":
System.out.println(emailResponse.getTextContent());
break;
case "LastMailServer":
System.out.println(emailResponse.getTextContent());
break;
case "GoodEmail":
System.out.println(emailResponse.getTextContent());
default:
break;
}
}
break;
default:
break;
}
}




break;




default:
break;
}


} else if (node.getNodeType()==Node.TEXT_NODE) {
System.out.println("reading Node.TEXT_NODE");
//do nothing here most likely, as the response nearly never has mixed content type
//this is just for your reference
}
}
// print SOAP Response
System.out.println("Response SOAP Message:");
soapResponse.writeTo(System.out);


soapConnection.close();
}


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


String serverURI = "http://ws.cdyne.com/";


// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("example", serverURI);


/*
Constructed SOAP Request Message:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:example="http://ws.cdyne.com/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<example:VerifyEmail>
<example:email>mutantninja@gmail.com</example:email>
<example:LicenseKey>123</example:LicenseKey>
</example:VerifyEmail>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
*/


// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("VerifyEmail", "example");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("email", "example");
soapBodyElem1.addTextNode("mutantninja@gmail.com");
SOAPElement soapBodyElem2 = soapBodyElem.addChildElement("LicenseKey", "example");
soapBodyElem2.addTextNode("123");


MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI  + "VerifyEmail");


soapMessage.saveChanges();


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


return soapMessage;
}

}

来自 肥皂水联机 SoapClient 计算器的计算器 SOAP 服务测试

从输入 SoapEnvelopeXMLSoapDataXml生成 SoapMessage对象。

SoapEnvelopeXML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<tem:Add xmlns:tem="http://tempuri.org/">
<tem:intA>3</tem:intA>
<tem:intB>4</tem:intB>
</tem:Add>
</soapenv:Body>
</soapenv:Envelope>

使用以下代码获取 SoapMessage 对象。

MessageFactory messageFactory = MessageFactory.newInstance();
MimeHeaders headers = new MimeHeaders();
ByteArrayInputStream xmlByteStream = new ByteArrayInputStream(SoapEnvelopeXML.getBytes());
SOAPMessage soapMsg = messageFactory.createMessage(headers, xmlByteStream);

SoapDataXml

<tem:Add xmlns:tem="http://tempuri.org/">
<tem:intA>3</tem:intA>
<tem:intB>4</tem:intB>
</tem:Add>

使用下面的代码获取 SoapMessage 对象。

public static SOAPMessage getSOAPMessagefromDataXML(String saopBodyXML) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource ips = new org.xml.sax.InputSource(new StringReader(saopBodyXML));
Document docBody = dBuilder.parse(ips);
System.out.println("Data Document: "+docBody.getDocumentElement());
    

MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMsg = messageFactory.createMessage();
    

SOAPBody soapBody = soapMsg.getSOAPPart().getEnvelope().getBody();
soapBody.addDocument(docBody);
    

return soapMsg;
}

通过获取 SoapMessage 对象。很明显,SoapXML 是有效的。然后准备访问服务以获得响应。它可以通过许多方式实现。

  1. 使用 WSDL 生成的客户端代码。
java.net.URL endpointURL = new java.net.URL(endPointUrl);
javax.xml.rpc.Service service = new org.apache.axis.client.Service();
((org.apache.axis.client.Service) service).setTypeMappingVersion("1.2");
CalculatorSoap12Stub obj_axis = new CalculatorSoap12Stub(endpointURL, service);
int add = obj_axis.add(10, 20);
System.out.println("Response: "+ add);
  1. 使用 javax.xml.soap.SOAPConnection
public static void getSOAPConnection(SOAPMessage soapMsg) throws Exception {
System.out.println("===== SOAPConnection =====");
MimeHeaders headers = soapMsg.getMimeHeaders(); // new MimeHeaders();
headers.addHeader("SoapBinding",   serverDetails.get("SoapBinding") );
headers.addHeader("MethodName",    serverDetails.get("MethodName") );
headers.addHeader("SOAPAction",    serverDetails.get("SOAPAction") );
headers.addHeader("Content-Type",  serverDetails.get("Content-Type"));
headers.addHeader("Accept-Encoding", serverDetails.get("Accept-Encoding"));
if (soapMsg.saveRequired()) {
soapMsg.saveChanges();
}
    

SOAPConnectionFactory newInstance = SOAPConnectionFactory.newInstance();
javax.xml.soap.SOAPConnection connection = newInstance.createConnection();
SOAPMessage soapMsgResponse = connection.call(soapMsg, getURL( serverDetails.get("SoapServerURI"), 5*1000 ));
    

getSOAPXMLasString(soapMsgResponse);
}
  1. 表单 HTTP 连接类 org.apache.commons.httpclient
public static void getHttpConnection(SOAPMessage soapMsg) throws SOAPException, IOException {
System.out.println("===== HttpClient =====");
HttpClient httpClient = new HttpClient();
HttpConnectionManagerParams params = httpClient.getHttpConnectionManager().getParams();
params.setConnectionTimeout(3 * 1000); // Connection timed out
params.setSoTimeout(3 * 1000);         // Request timed out
params.setParameter("http.useragent", "Web Service Test Client");


PostMethod methodPost = new PostMethod( serverDetails.get("SoapServerURI") );
methodPost.setRequestBody( getSOAPXMLasString(soapMsg) );
methodPost.setRequestHeader("Content-Type", serverDetails.get("Content-Type") );
methodPost.setRequestHeader("SoapBinding",  serverDetails.get("SoapBinding") );
methodPost.setRequestHeader("MethodName",   serverDetails.get("MethodName") );
methodPost.setRequestHeader("SOAPAction",   serverDetails.get("SOAPAction") );


methodPost.setRequestHeader("Accept-Encoding", serverDetails.get("Accept-Encoding"));


try {
int returnCode = httpClient.executeMethod(methodPost);
if (returnCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.out.println("The Post method is not implemented by this URI");
methodPost.getResponseBodyAsString();
} else {
BufferedReader br = new BufferedReader(new InputStreamReader(methodPost.getResponseBodyAsStream()));
String readLine;
while (((readLine = br.readLine()) != null)) {
System.out.println(readLine);
}
br.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
methodPost.releaseConnection();
}
}
public static void accessResource_AppachePOST(SOAPMessage soapMsg) throws Exception {
System.out.println("===== HttpClientBuilder =====");
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
URIBuilder builder = new URIBuilder( serverDetails.get("SoapServerURI") );
HttpPost methodPost = new HttpPost(builder.build());
RequestConfig config = RequestConfig.custom()
.setConnectTimeout(5 * 1000)
.setConnectionRequestTimeout(5 * 1000)
.setSocketTimeout(5 * 1000)
.build();
methodPost.setConfig(config);
HttpEntity xmlEntity = new StringEntity(getSOAPXMLasString(soapMsg), "utf-8");
methodPost.setEntity(xmlEntity);
        

methodPost.setHeader("Content-Type", serverDetails.get("Content-Type"));
methodPost.setHeader("SoapBinding", serverDetails.get("SoapBinding") );
methodPost.setHeader("MethodName", serverDetails.get("MethodName") );
methodPost.setHeader("SOAPAction", serverDetails.get("SOAPAction") );
methodPost.setHeader("Accept-Encoding", serverDetails.get("Accept-Encoding"));
    

// Create a custom response handler
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
@Override
public String handleResponse( final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status <= 500) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
return "";
}
};
String execute = httpClient.execute( methodPost, responseHandler );
System.out.println("AppachePOST : "+execute);
}

完整例子:

public class SOAP_Calculator {
static HashMap<String, String> serverDetails = new HashMap<>();
static {
// Calculator
serverDetails.put("SoapServerURI", "http://www.dneonline.com/calculator.asmx");
serverDetails.put("SoapWSDL", "http://www.dneonline.com/calculator.asmx?wsdl");
serverDetails.put("SoapBinding", "CalculatorSoap");        // <wsdl:binding name="CalculatorSoap12" type="tns:CalculatorSoap">
serverDetails.put("MethodName", "Add");                    // <wsdl:operation name="Add">
serverDetails.put("SOAPAction", "http://tempuri.org/Add"); // <soap12:operation soapAction="http://tempuri.org/Add" style="document"/>
serverDetails.put("SoapXML", "<tem:Add xmlns:tem=\"http://tempuri.org/\"><tem:intA>2</tem:intA><tem:intB>4</tem:intB></tem:Add>");
        

serverDetails.put("Accept-Encoding", "gzip,deflate");
serverDetails.put("Content-Type", "");
}
public static void callSoapService( ) throws Exception {
String xmlData = serverDetails.get("SoapXML");
        

SOAPMessage soapMsg = getSOAPMessagefromDataXML(xmlData);
System.out.println("Requesting SOAP Message:\n"+ getSOAPXMLasString(soapMsg) +"\n");
        

SOAPEnvelope envelope = soapMsg.getSOAPPart().getEnvelope();
if (envelope.getElementQName().getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/envelope/")) {
System.out.println("SOAP 1.1 NamespaceURI: http://schemas.xmlsoap.org/soap/envelope/");
serverDetails.put("Content-Type", "text/xml; charset=utf-8");
} else {
System.out.println("SOAP 1.2 NamespaceURI: http://www.w3.org/2003/05/soap-envelope");
serverDetails.put("Content-Type", "application/soap+xml; charset=utf-8");
}
        

getHttpConnection(soapMsg);
getSOAPConnection(soapMsg);
accessResource_AppachePOST(soapMsg);
}
public static void main(String[] args) throws Exception {
callSoapService();
}


private static URL getURL(String endPointUrl, final int timeOutinSeconds) throws MalformedURLException {
URL endpoint = new URL(null, endPointUrl, new URLStreamHandler() {
protected URLConnection openConnection(URL url) throws IOException {
URL clone = new URL(url.toString());
URLConnection connection = clone.openConnection();
connection.setConnectTimeout(timeOutinSeconds);
connection.setReadTimeout(timeOutinSeconds);
//connection.addRequestProperty("Developer-Mood", "Happy"); // Custom header
return connection;
}
});
return endpoint;
}
public static String getSOAPXMLasString(SOAPMessage soapMsg) throws SOAPException, IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMsg.writeTo(out);
// soapMsg.writeTo(System.out);
String strMsg = new String(out.toByteArray());
System.out.println("Soap XML: "+ strMsg);
return strMsg;
}
}

@ 请参阅 http://sofa.uqam.ca/soda/webservices.php上的一些 WebServices 列表

这可能会帮助那些将 xml 请求作为字符串并希望从 Java 访问肥皂请求的人,比如我。
如果您有 WSDL,您可以使用该 WSDL 文件在 SoapUI 中创建一个新的肥皂请求。
它会自动为输入请求生成结构/XML。

如果您有来自 SoapUI 的输入请求 xml,可以使用下面这些简单的 Java 代码来调用 Soap 服务:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class SimpleSoapClient {


public static void main(String args[]) throws IOException {
        

String address="Hyderabad";


/* place your xml request from soap ui below with necessary changes in parameters*/
    

String xml="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://www.YourUrlAsPerWsdl.com/\">\r\n" +
"   <soapenv:Header/>\r\n" +
"   <soapenv:Body>\r\n" +
"      <ws:callRest>\r\n" +
"         <name>"+"Hello"+"</name>\r\n" +
"         <address>"+address+"</address>\r\n" +
"      </ws:callRest>\r\n" +
"   </soapenv:Body>\r\n" +
"</soapenv:Envelope>";
String responseF=callSoapService(xml);
System.out.println(responseF);
}
    



}


static String callSoapService(String soapRequest) {
try {
String url = "https://gogle.com/service/hello"; // replace your URL here
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
     

// change these values as per soapui request on top left of request, click on RAW, you will find all the headers
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","text/xml; charset=utf-8");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(soapRequest);
wr.flush();
wr.close();
String responseStatus = con.getResponseMessage();
System.out.println(responseStatus);
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
     

// You can play with response which is available as string now:
String finalvalue= response.toString();
     

// or you can parse/substring the required tag from response as below based your response code
finalvalue= finalvalue.substring(finalvalue.indexOf("<response>")+10,finalvalue.indexOf("</response>")); */
     

return finalvalue;
}
catch (Exception e) {
return e.getMessage();
}
}

}