工作肥皂客户端示例
Posted
技术标签:
【中文标题】工作肥皂客户端示例【英文标题】:Working Soap client example 【发布时间】:2013-04-03 15:45:36 【问题描述】:我试图在 JAVA 中找到一个简单的 (ha) SOAP 示例和一个工作服务,但我似乎发现的任何一个都不起作用。
我从这个example 尝试过这个one,但它只是不起作用,它要求我输入一个正斜杠,但它在那里并且没有任何反应。
那么有没有人知道任何 SOAP 示例链接,我可以下载/请求和弄乱?
感谢您的帮助。
【问题讨论】:
在 2019 年寻找有关这方面的文档更加困难...... 【参考方案1】:要在 Java 中实现简单的 SOAP 客户端,您可以使用 SAAJ 框架(它随 JSE 1.6 及更高版本提供,但在 Java 11 中再次被删除):
SOAP with Attachments API for Java (SAAJ) 主要用于直接处理在任何 Web 服务 API 中发生在幕后的 SOAP 请求/响应消息。它允许开发人员直接发送和接收肥皂消息,而不是使用 JAX-WS。
请看下面一个使用 SAAJ 的 SOAP Web 服务调用的工作示例(运行它!)。它调用this web service。
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;
【讨论】:
收到此错误<faultcode>soap:Client</faultcode><faultstring>Server did not recognize the value of HTTP Header SOAPAction: .</faultstring>
缺少 SOAPAction HTTP 标头。通过添加行MimeHeaders headers = soapMessage.getMimeHeaders(); headers.addHeader("SOAPAction", "http://ws.cdyne.com/VerifyEmail");
更正它。我现在认为没有它之前它工作很奇怪。 :)
你知道解析结果元素的好方法吗?
将它们解析成一个对象,或者只是将其制作成一个Map
或String
s 以便于访问?
我需要通过这个电话传递凭据,你能帮我用凭据打电话吗【参考方案2】:
这可能会帮助那些将 xml 请求作为字符串并希望像我一样从 Java 中获得 soap 请求的人。 如果您有 WSDL,您可以使用该 WSDL 文件在 SoapUI 中创建一个新的 soap 请求。 它会自动为输入请求生成结构/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();
【讨论】:
【参考方案3】:来自SoapUI、Online SoapClient Calculator 的计算器 SOAP 服务测试
从输入 SoapEnvelopeXML
和 SoapDataXml
生成 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 对象。很明显,Soap XML 是有效的。然后准备点击服务以获得响应。它可以通过多种方式完成。
-
使用客户端代码生成表单 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);
-
使用
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);
-
形成 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列表
【讨论】:
【参考方案4】:是的,如果您可以获取任何 WSDL 文件,那么您可以使用 SoapUI 创建该服务的模拟服务,并完成单元测试请求。我created an example of this (using Maven) that you can try out。
【讨论】:
链接到你的例子返回 404。你能把它找回来吗?【参考方案5】: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;
【讨论】:
【参考方案6】: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;
【讨论】:
【参考方案7】:对于 WSDL 的基本身份验证,接受的答案代码会引发错误。请尝试以下方法
Authenticator.setDefault(new Authenticator()
@Override
protected PasswordAuthentication getPasswordAuthentication()
return new PasswordAuthentication("username","password".toCharArray());
);
【讨论】:
不应该是 "password".toBase64()" 之类的吗?这与您将用于 javax.email 的代码块相同。以上是关于工作肥皂客户端示例的主要内容,如果未能解决你的问题,请参考以下文章