Reputation: 65
I freely admit that I am out of my depth here regarding SOAP connectivity. I used SOAP UI to generate Java classes from a wsdl location given to me by a third party.
This generated an interface:
@WebService(name = "Ext_Webservice_SoapPort", targetNamespace = "https://ws.185red.com")
@SOAPBinding(style = SOAPBinding.Style.RPC)
@XmlSeeAlso({ ObjectFactory.class })
public interface ExtWebserviceSoapPort
{
@WebMethod(action = "https://ws.185red.com#acceptArrayOfInt")
@WebResult(partName = "return")
boolean acceptArrayOfInt(@WebParam(name = "param", partName = "param") final ArrayOfInt p0);
@WebMethod(action = "https://ws.185red.com#acceptArrayOfStrings")
@WebResult(partName = "return")
boolean acceptArrayOfStrings(@WebParam(name = "param", partName = "param") final ArrayOfString p0);
@WebMethod(action = "https://ws.185red.com#acceptArrayOfComplexType")
@WebResult(partName = "return")
boolean acceptArrayOfComplexType(@WebParam(name = "param", partName = "param") final ArrayOfExtWebserviceComplextypePerson p0);
@WebMethod(action = "https://ws.185red.com#acceptComplexType")
@WebResult(partName = "return")
boolean acceptComplexType(@WebParam(name = "param", partName = "param") final ExtWebserviceComplexTypePerson p0);
@WebMethod(action = "https://ws.185red.com#returnArrayOfInt")
@WebResult(partName = "return")
ArrayOfInt returnArrayOfInt();
@WebMethod(action = "https://ws.185red.com#returnArrayOfStrings")
@WebResult(partName = "return")
ArrayOfString returnArrayOfStrings();
@WebMethod(action = "https://ws.185red.com#returnArrayOfComplexType")
@WebResult(partName = "return")
ArrayOfExtWebserviceComplextypePerson returnArrayOfComplexType();
@WebMethod(action = "https://ws.185red.com#returnComplexType")
@WebResult(partName = "return")
ExtWebserviceComplexTypePerson returnComplexType();
@WebMethod(action = "https://ws.185red.com#login")
@WebResult(partName = "return")
String login(@WebParam(name = "username", partName = "username") final String p0, @WebParam(name = "password", partName = "password") final String p1);
@WebMethod(action = "https://ws.185red.com#logout")
@WebResult(partName = "return")
boolean logout();
@WebMethod(operationName = "FetchData", action = "https://ws.185red.com#FetchData")
@WebResult(partName = "return")
ArrayOfExtWebserviceComplextypeRecordwithoutkey fetchData(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "criteria", partName = "criteria") final ArrayOfExtWebserviceComplextypeSearchcriteria p1, @WebParam(name = "keysToFetch", partName = "keysToFetch") final ArrayOfString p2);
@WebMethod(operationName = "FetchDataCount", action = "https://ws.185red.com#FetchDataCount")
@WebResult(partName = "return")
int fetchDataCount(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "criteria", partName = "criteria") final ArrayOfExtWebserviceComplextypeSearchcriteria p1);
@WebMethod(operationName = "FetchRecordByUniqueKey", action = "https://ws.185red.com#FetchRecordByUniqueKey")
@WebResult(partName = "return")
ExtWebserviceComplexTypeRecordWithKey fetchRecordByUniqueKey(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "uniqueKey", partName = "uniqueKey") final String p1, @WebParam(name = "tokensToFetch", partName = "tokensToFetch") final ArrayOfString p2);
@WebMethod(operationName = "UpdateDateFulfillment", action = "https://ws.185red.com#UpdateDateFulfillment")
@WebResult(partName = "return")
ArrayOfExtWebserviceComplextypeUpdatedataresult updateDateFulfillment(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "values", partName = "values") final ArrayOfExtWebserviceComplextypeRecordwithkey p1);
@WebMethod(operationName = "UpdateData", action = "https://ws.185red.com#UpdateData")
@WebResult(partName = "return")
ArrayOfExtWebserviceComplextypeUpdatedataresult updateData(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "values", partName = "values") final ArrayOfExtWebserviceComplextypeRecordwithkey p1, @WebParam(name = "markAsComplete", partName = "markAsComplete") final boolean p2, @WebParam(name = "prepopulate", partName = "prepopulate") final boolean p3);
@WebMethod(operationName = "DeleteData", action = "https://ws.185red.com#DeleteData")
@WebResult(partName = "return")
int deleteData(@WebParam(name = "formId", partName = "formId") final int p0, @WebParam(name = "criteria", partName = "criteria") final ArrayOfExtWebserviceComplextypeSearchcriteria p1);
}
I feel as if these methods are all set up, I simply need to pass in the data fields in order to call them. However I'm not sure exactly how to do that.
For example, the first method I would want to call is the login method. My understanding would be that I simply set the username and password and call the method. Then check for a return string. Like so:
@WebMethod(action = "https://ws.185red.com#login")
@WebResult(partName = "return")
@RequestMapping("/getAllTest")
public String login(@WebParam(name = "username", partName = "username") String username, @WebParam(name = "password", partName = "password") String password) {
username = "";
password = "";
//webresult return?
return "";
}
Is there something else I would need to do in order to A) actually send the request out and B)see the response? I believe I should just have to set the variables and it should be all set. I understand that I would need to actually call the request but am I not doing that by setting the WebMethod/WebResult annotations and pointing it to the endpoint location on my local webpage?
Again completely out of my depth here, if someone could point me to some documentation I'd be extremely grateful.
Thanks in advance.
Upvotes: 2
Views: 3127
Reputation: 24590
Since you mention you are out of your depth here, I'll start with an introduction.
A SOAP web service is just an API exposed over the web that can be invoked with HTTP POST methods by sending (and then receiving) an XML message as payload. This XML message must have a specific form, specified by both the SOAP protocol as well as the documentation of the web service, commonly also in machine readable format as a WSDL.
You can build these messages yourself by whatever way available (even string concatenation can work), and then make HTTP requests with whatever HTTP library you prefer. But you then must also parse the XML response you receive from the web service to extract the useful values out of it. And that's a pain in the butt.
Because SOAP is a protocol with defined rules, and the WSDL describes the web service contract, you can use the WSDL to generate client code that handles these things for you. It will build the XML request messages and parse the XML response messages, and will invoke the operations of the service by making appropriate HTTP calls for you. What you will get from your client will be familiar Java objects and methods that you can work with without concern for what happens on the wire.
You did this with SoapUI, but I'm not sure what kind of client code you got back from that. You are showing an interface, but that's not enough to call the service. It just defined the contract with all of the operations of the service. Those annotations just add metadata about the operations. They don't invoke the methods. For that you need a proper client not just a contract.
The annotations shown in your question are part of the JAX-WS specification. You need a JAX-WS implementation of the client to handle the call to the service for you. Something like Apache CXF for example.
I would suggest you don't use SoapUI to generate code. Use your implementation of choice to generate the code from the WSDL. For example, Apache CXF has a command line tool (also a Maven plugin) called wsdl2java
that can generate the client code for you. Then it's a matter of just instantiating the generated client and call methods on it like any Java object. The methods will receive Java objects and return java objects. Everything else related to SOAP or HTTP requests is handled by the client for you.
For example:
wsdl2java -client -keep -d C:\temp http://www.dneonline.com/calculator.asmx?WSDL
Will generate a bunch of classes for this online demo web service: http://www.dneonline.com/calculator.asmx?WSDL
Add.java
AddResponse.java
Calculator.java
CalculatorSoap.java
CalculatorSoap_CalculatorSoap12_Client.java
CalculatorSoap_CalculatorSoap_Client.java
Divide.java
DivideResponse.java
Multiply.java
MultiplyResponse.java
ObjectFactory.java
package-info.java
Subtract.java
SubtractResponse.java
The files contain a client class with a main()
method inside that shows how you can invoke the service operations. For example:
private static final QName SERVICE_NAME = new QName("http://tempuri.org/", "Calculator");
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = Calculator.WSDL_LOCATION;
// ...
Calculator ss = new Calculator(wsdlURL, SERVICE_NAME);
CalculatorSoap port = ss.getCalculatorSoap();
// ...
System.out.println("Invoking add...");
int _add_intA = 0;
int _add_intB = 0;
int _add__return = port.add(_add_intA, _add_intB);
System.out.println("add.result=" + _add__return);
// ...
}
These generated classes extend classes from the Apache CXF framework and handle the calls for you.
This particular example contains two client classes because the demo service I've used to explain this has two bindings, for SOAP 1.1 and SOAP 1.2. The client code to invoke the service over the two SOAP versions is almost the same, you just need to select the desired port first.
Hope this explains things enough so that you now understand what you need to do to call your service.
Upvotes: 3