使用JAX-WS和WS-Addressing来使用SOAP

时间:2017-03-29 14:48:14

标签: java web-services soap client jax-ws

我使用wsimport创建了一些JAX-WS工件。这是我使用的wsimport命令。

wsimport -b "C:\temp\Customization.xml" -B-XautoNameResolution -d C:\temp -extension -J-Djavax.xml.accessExternalSchema=all -J-Djavax.xml.accessExternalDTD=all -keep -verbose -XadditionalHeaders -Xnocompile https://api.sendwordnow.com/webservices/v3/users.svc?wsdl

这似乎有效。至少我认为确实如此。 wsimport创建了许多包甚至是公共接口。现在这里是我试图连接到我认为是有效端点的代码片段。

HttpTransportPipe.dump = true;
Users users = new Users();
IUsers iUsers = users.getWSHttpBindingIUsers();
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://api.sendwordnow.com/webservices/v3/Users.svc");
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "somename");
((BindingProvider)iUsers).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "somepassword");
iUsers.echoAuthenticated("This is an echo test.");
System.out.println();

我尝试了不同的方法来设置用户名和密码,但我总是收到HTTP传输错误:java.net.ConnectException:连接超时:连接。我跳转到SoapUI并使用来自https://api.sendwordnow.com/webservices/v3/users.svc?wsdl的WSDL创建了一个新项目。我可以向https://api.sendwordnow.com/webservices/v3/Users.svc提交请求并通过适当的身份验证并将WSS-Password Type属性设置为PasswordText,我可以成功调用EchoAuthenticated。这是SoapUI的输出。

Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "POST /webservices/v3/Users.svc HTTP/1.1[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Accept-Encoding: gzip,deflate[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Content-Type: application/soap+xml;charset=UTF-8;action="http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated"[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Authorization: Basic c2lyaXVzYXBpOnRlbXBvcmFyeTEyMw==[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Content-Length: 1224[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Host: api.sendwordnow.com[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "Connection: Keep-Alive[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "[\r][\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v3="http://www.sendwordnow.com/contract/users/v3">[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:UsernameToken wsu:Id="UsernameToken-838F7D896DB9148E2414907229483491"><wsse:Username>somename</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somepassword</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">QpJwiZjZex+3ikqVWZp+Yw==</wsse:Nonce><wsu:Created>2017-03-28T17:42:28.348Z</wsu:Created></wsse:UsernameToken></wsse:Security><wsa:Action>http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated</wsa:Action></soap:Header>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   <soap:Body>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "      <v3:EchoAuthenticated>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "         <!--Optional:-->[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "         <v3:value>This is an echo test.</v3:value>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "      </v3:EchoAuthenticated>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "   </soap:Body>[\n]"
Tue Mar 28 12:42:28 CDT 2017:DEBUG:>> "</soap:Envelope>"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "HTTP/1.1 200 OK[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Content-Type: application/soap+xml; charset=utf-8[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Server: Microsoft-IIS/8.5[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Date: Tue, 28 Mar 2017 17:42:29 GMT[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "Content-Length: 887[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "[\r][\n]"
Tue Mar 28 12:42:29 CDT 2017:DEBUG:<< "<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><a:Action s:mustUnderstand="1">http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticatedResponse</a:Action><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><u:Timestamp u:Id="_0"><u:Created>2017-03-28T17:42:29.695Z</u:Created><u:Expires>2017-03-28T17:47:29.695Z</u:Expires></u:Timestamp></o:Security></s:Header><s:Body><EchoAuthenticatedResponse xmlns="http://www.sendwordnow.com/contract/users/v3"><EchoAuthenticatedResult>This is the Users service answering back. The value you sent was: This is an echo test.</EchoAuthenticatedResult></EchoAuthenticatedResponse></s:Body></s:Envelope>"

看起来我缺少wsa:Action,wsse:password类型和wsse:Nonce EncodingType。至少那是SoapUI请求中的内容。我觉得我这一切都错了。我显然需要那些缺少的组件,但我似乎无法弄清楚如何实际实现它们。任何建议都会非常有用。我以为我会收到一些身份验证错误,但我似乎无法做到这一点。

更新1

我不确定我是否接近或不接近此事。这是SoapUI请求。

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v3="http://www.sendwordnow.com/contract/users/v3">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>
*********</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
**********</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
zhVqVXnkOsPCFRZolLSWtw==</wsse:Nonce>
<wsu:Created>
2017-03-29T14:05:54.820Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<wsa:Action>
http://www.sendwordnow.com/contract/users/v3/IUsers/EchoAuthenticated
</wsa:Action>
</soap:Header>
   <soap:Body>
      <v3:EchoAuthenticated>
         <v3:value>
Test Message</v3:value>
      </v3:EchoAuthenticated>
   </soap:Body>
</soap:Envelope>

这是一段代码片段。

SOAPElement security = header.addChildElement("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement userToken = security.addChildElement("UsernameToken", "wsse");
userToken.addChildElement("Username", "wsse").addTextNode("someusername");
userToken.addChildElement("Password", "wsse").addTextNode("somepassword");
userToken.addChildElement("Nonce", "wsse").addTextNode("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
userToken.addChildElement("Password", "wsse").addTextNode("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
userToken.addChildElement("Action", "wsa");

我不再超时,但我现在收到此错误。

com.sun.xml.internal.ws.streaming.XMLStreamReaderException: unexpected XML tag. expected: {http://www.sendwordnow.com/contract/users/v3}EchoAuthenticatedResponse but found: {http://www.sendwordnow.com/contract/users/v3}EchoAuthenticated

我是否需要将wsa:action设置为特定的URL?

1 个答案:

答案 0 :(得分:0)

虽然这不是唯一的一块拼图。

security.addAttribute(soapFactory.createName("S:mustUnderstand"),"1");

我一直在使用它。

security.addAttribute(soapFactory.createName("SOAP:mustUnderstand"),"True");

构建WSSE和WSA元素树的其他一些变化已经完成,但是mustUnderstand真的给我带来了一堆悲伤。一切都很好。