This is a pretty basic question but I don't really see an answer anywhere. I created a webservice using wsimport and a wsdl.
It created a large number of files. Most of them appear to be beans representing the methods of the webservice. There are also classes called Gateway, Gateway SOAP, and ObjectFactory. How exactly do you go about actually calling the web-service with these methods?
You should do something like this:
Gateway svc = new Gateway();
GatewaySOAP port = svc.getGatewaySOAP();
MyRequestClass rq = new MyRequestClass();
rq.setSomething(2);
MyResponseClass rs = port.doMyVeryOwnJob(rq);
System.out.println("Result is: " + rs.getSomethingElse());
Related
I'm in the process of creating a Java web services client from a wsdl. I used Eclipses's Dynamic Web Project and new Web Services Client to generate the code with wsdl2java with Apache Axis 1.4. I need to add SOAP authentication to this code in order for it to work with the service. I couldn't find a place to do that in the generated code. After copious research I found this, which I've used as the backbone for my code so far.
Adding ws-security to wsdl2java generated classes
Before I was getting a "Error occurred while processing security for the message" or something along those lines. Now I am getting
"Exception: Did not understand "MustUnderstand" header(s):{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security Message: null"
I've tried many things to get past this exception. This is the code I've arrived at now.
javax.xml.namespace.QName headerName = new javax.xml.namespace.QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
org.apache.axis.message.SOAPHeaderElement header = new org.apache.axis.message.SOAPHeaderElement(headerName);
header.setActor(null);
header.setMustUnderstand(true);
// Add the UsernameToken element to the WS-Security header
javax.xml.soap.SOAPElement utElem = header.addChildElement("UsernameToken");
utElem.setAttribute("Id", "uuid-3453f017-d595-4a5b-bc16-da53e5831cd1-1");
javax.xml.soap.SOAPElement userNameElem = utElem.addChildElement("Username");
userNameElem.setValue("username");
javax.xml.soap.SOAPElement passwordElem = utElem.addChildElement("Password");
passwordElem.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwordElem.setValue("password");
header.setProcessed(true);
// Finally, attach the header to the binding.
setHeader(header)
This code is located in my Binding_ServiceStub class (in its' createCall method).
We have created clients in both C# and VB with this wsdl, and there it's as easy as just changing the ClientCredentials variable which is an extension of the proxy class generated. I was hoping for something similar here.
Here's the security policy from the wsdl code as well.
<wsp:Policy><sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"><wsp:Policy><sp:WssUsernameToken10/></wsp:Policy></sp:UsernameToken></wsp:Policy>
Does anyone know what else I can do here? Why this exception is happening? I've tried many different combinations of prefixes and setProcesses and setMustUnderstand values all in vain (and based on my research of this exception).
And if anyone knows a way in which to add Soap header authentication to wsdl2java code I would take that too. Just need this to work and you would think something like this would be a little more straightforward or at least have more examples out there.
Update-
Confirmed that the same header passed using SOAPUI works fine. Must be something with the framework? I created a custom handler to process the SOAP Message but that didn't help. Is Axis 1.4 and JAX-RPC the problem? (I know they're outdated but still...)
Cool. I decided to just use Apache CXF as my framework and using this it's as easy as adding
javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider) port;
bp.getRequestContext().put("ws-security.username", username);
bp.getRequestContext().put("ws-security.password", password);
Wow that's much better. Don't use Axis 1.4 lesson learned.
In SOAP UI Web service testing,
User imports the Project in to the work space and mentions the End point. Enters the required data in the Request xml and runs to get the resulting response in xml format.
Is there a way we can achieve this using Java only without using the SoapUI tool. I guess the steps should be:
Create a Wsdl Project.
Create a xml request (in the required format)
Send the request to the end point (How to do this?)
Receive response and verify it.
Please help me how to do this using Java only(without using SOAP UI tool). Any links/code will be greatly helpful.
Thanks,
Mike
Use soapUI API.
;
Here are some useful links:
http://www.soapui.org/Developers-Corner/integrating-with-soapui.html
http://pritikaur23.wordpress.com/2013/06/16/saving-a-soapui-project-and-sending-requests-using-soapui-api/
I used the following code to create a project:
File projectFile = new File(filePath);
SoapUI.setSoapUICore(new StandaloneSoapUICore(true));
WsdlProject project = new WsdlProject();
project.setName(projectName);
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, url);
for (WsdlInterface wsdl : wsdls) {
int c = wsdl.getOperationCount();
String reqContent = "";
for (int j = 0; j < c; j++) {
WsdlOperation op = wsdl.getOperationAt(j);
reqContent = op.createRequest(true);
WsdlRequest req = op.addNewRequest(requestName);
req.setRequestContent(reqContent );
}
}
project.saveIn(projectFile);
SoapUI.shutdown();
You can create client and pass in HTTP Request test request populated with needed parameter for testing purpose, below mention question has some useful insights.
Java Web service testing
I'm using JAX-WS standard stuff with wsimport http://localhost/Order.wsdl to generate client stub classes.
The live web service is on a different host, so I need to supply a url when I make the service call. My approach so far has been like this (classes below are generated from wsimport):
1. OrderService s = new OrderService (
new URL("https://live/WS/Order"),
new QName(...));
2. OrderServicePort port = s.getOrderServicePort();
3. configureHttpCertificatesStuff(port) // Set up ssl stuff with the port
4. port.placeOrder(args); // The actual ws call
First: Is this the correct way of specifying the url?
Second: It seems the constructor in line 1 actually makes a network call to the new URL! This results in an exception (due to https not being configured), so I never get to the next line.
Background: I am implementing two-way ssl auth as outlined in this question. This means I need to configure ssl stuff in the port before the service call. I can't have the constructor make any connection before I've configured the ssl layer correctly for obvious reasons...
Update:
Apparenty the url is to the WSDL, not the endpoint when using jax-ws standard. This tripped me up. Loading the WSDL directly from file solved that problem.
Setting the endpoint url is done like this:
BindingProvider b = (BindingProvider) port;
b.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl);
One solution would be to have your build process arrange for the WSDL file processed by wsimport to become a class path resource for your app. There are any number of ways to do this, but lets assume you take a JAR-per-service approach. So, you'd run Order.wsdl through wsimport and take the resulting classes, like OrderService and OrderServicePort, and stuff them into order-service.jar. The other thing you could do would be to stuff a copy of Order.wsdl into that same JAR at META-INF/wsdl/Order.wsdl. Assuming that JAR file is then part of the class path for your app, you can get the WSDL's URL by doing:
URL wsdlLocation = Thread.currentThread().getContextClassLoader().getResource("META-INF/wsdl/Order.wsdl");
This seems like it should be simple, but maybe I'm missing something. I just want to make a SOAP call in Java, preferrably using only built-in APIs. I'm a little overwhelmed looking at javax.xml.soap package in the Java documentation. I have tried searching Google, but it seems like all the results are from 2000-2002, and they are all talking about libraries that can be used for SOAP calls (before SOAP libraries were built in, I guess).
I don't need to handle the SOAP request; only make one. This site has an example that is pretty simple, but it doesn't use the built-in Java SOAP libraries. How would I do basically the same thing using core Java?
// Create the parameters
Vector params = new Vector( );
params.addElement(
new Parameter("flightNumber", Integer.class, flightNumber, null));
params.addElement(
new Parameter("numSeats", Integer.class, numSeats, null));
params.addElement(
new Parameter("creditCardType", String.class, creditCardType, null));
params.addElement(
new Parameter("creditCardNumber", Long.class, creditCardNum, null));
// Create the Call object
Call call = new Call( );
call.setTargetObjectURI("urn:xmltoday-airline-tickets");
call.setMethodName("buyTickets");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setParams(params);
// Invoke
Response res = call.invoke(new URL("http://rpc.middleearth.com"), "");
// Deal with the response
Soap has changed a lot since the early days. You can do things like what you describe, but it is not common.
A more common practice now is to use a wsdl2java tool to generate a client API from a WSDL description of the service. That will give you a nice, clean, API to call.
Apache CXF is one place to go for this sort of thing.
One proviso is rpc/encoded. If you are dealing with an old service, it might be rpc/encoded, and in that case your best bet is Apache Axis 1.x. Everything else has run away from rpc/encoded.
The simplest way is soap-ws library:
https://github.com/reficio/soap-ws
SoapClient client = SoapClient.builder()
.endpointUrl("http://rpc.middleearth.com")
.build();
client.post(envelope);
I need to call a web service using ksoap2, I have been doign this successfully up till the point where I need to pass a more complex type to the web service.
Does anybody have an example of passing a complex type to a webservice, preferably, only using SoapObject (the object in question is only Strings and dateTimes.
Thanks
in advance
Here is a working tutorial for complex types and arrays with KSOAP . Hope it helps.
Figured out how to do it. Simply used a SoapObject as a property.
I think you can use this android web service client open source tool.
Where you needn't use the soap Object or think with the soap envelop its just like call a method of a service.
say, for a service say ComplexReqService with param ComplexRequest you have to just write :
ComplexReqService service = new ComplexReqService();
CoplextReqPort port = service.getPort();
String resp = port.getResponse ( new ComplexRequest() );
In this way, It will support the complex response as well.