Spring WS force SOAP endpoint operation name - java

I am implementing a SOAP WS with spring, I have my XSDs, then I add my endpoints with annotations such as:
#Endpoint
public class StuffRequestEndpoint {
#PayloadRoot(namespace = "urn:mycomp-com/xyz/ws/msg", localPart = "StuffRequest")
public
#ResponsePayload
StuffResponse requestStuff(#RequestPayload StuffRequest request) {
The problem I have is that the produced WSDL has a funny operation name:
<wsdl:operation name="Stuff">
<soap:operation soapAction=""/>
<wsdl:input name="StuffRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="StuffResponse">
<soap:body use="literal"/>
</wsdl:output>
How could I override the produced operation name?
Thanks.

Well I see this is pretty old and I too do not have a direct answer, what I did was basically renaming the object to what I want the action be named like.
Since Spring-WS looks at the xsd and if it sees name with Request/Response suffix it creates an action with such name, e.g. object GetListOfCitiesRequest would be GetListOfCities action. In your case that could be something like this in XSD
<xs:element name="GetListOfCitiesRequest">
which would then appear like this wsdl generated by spring-ws
<wsdl:operation name="GetListOfCities">
<soap:operation soapAction=""/>
<wsdl:input name="GetListOfCitiesRequest">
<soap:body use="literal"/>
</wsdl:input>
</wsdl:operation>

Related

Making WSDL parameters optional

I'm trying to work with the Microsoft Exchange EWS protocol, for which Microsoft provide a WSDL file. I'm generate a JAX-WS client library from this using wsimport.
Unfortunately, Microsoft's WSDL file is faulty. One of the things it is getting wrong (apparently) is that all SOAP request parameters are defined as mandatory --- except they're not, they're optional, and in some situations I have to be able to not supply them.
Excerpt from the WSDL file:
<wsdl:operation name="GetUserAvailability">
<soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserAvailability" />
<wsdl:input>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="Impersonation" use="literal"/>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="TimeZoneContext" use="literal"/>
<soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
<soap:body parts="GetUserAvailabilityRequest" use="literal" />
<soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
</wsdl:input>
<wsdl:output>
...skipped...
</wsdl:output>
</wsdl:operation>
<wsdl:message name="GetUserAvailabilitySoapIn">
<wsdl:part name="GetUserAvailabilityRequest" element="tns:GetUserAvailabilityRequest" />
<wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
<wsdl:part name="TimeZoneContext" element="t:TimeZoneContext" />
<wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
</wsdl:message>
<xs:element name="ExchangeImpersonation" type="t:ExchangeImpersonationType"/>
If I call this with, say, service.getUserAvailability(request, null, null, version), then I get an <ExchangeImpersonation xsl:nil="true"/> element in the header, and the Exchange server complains about having an extraneous element.
So, I want to edit the WSDL file to make these parameters properly optional. I've tried adding various combinations of wsdl:required=false and minOccurs=0 to various places according to the docs, but wsimport appears to be ignoring them completely --- the resulting code is unchanged.
How do I do this?

Llist all the operations(Requests) from a wsdl url using Java

Is there a way to list all the operations from a wsdl url(by specifying end point and not from the xml) using Java?
Below is a sample endpoint.
http://www.webservicemart.com/uszip.asmx?WSDL
Please help.
you can use eviware/soapui's API for that.
You can create an interface with the designated WSDL, then use it to fetch operations.
int operationCount = wsdlInterface.getOperationCount();
for (int i = 0; i < operationCount; i++){
WsdlOperation wsdlOperation = wsdlInterface.getOperationAt(i);
String operationName = wsdlOperation.getName();
// you can use this name, add to an arraylist etc.
allOperations.add(wsdlOperation);
WsdlTestCase testCase = generateTestCase(wsdlTestSuite, operationName);
WsdlTestStep testStep = generateTestStep(wsdlOperation, testCase, operationName);
}
Documentation goes here:
https://www.soapui.org/apidocs/allclasses-noframe.html
You could use XPath to grab the tags:
XPath Syntax
<wsdl:binding name="USZipSoap" type="tns:USZipSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ValidateZip">
<soap:operation soapAction="http://webservicemart.com/ws/ValidateZip" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
Using the xpath expression:
//wsdl:operation
should return you all the nodes. A xpath lib for Java would be Jaxen
I hope that helps you further.
Thanks
Patrick

Specified throwing AxisFault in WSDL file

I generate my web service from WSDL file. But I need t o define in this file that my methods in SkeletonInterface thow Axis Fault Exception.
Smth like:
void method() throws AxisFault{....}
In which way I can do this (in WSDL).
Thanks.
In short, it's bad practice to reuse AxisFault for your own application faults. When I see AxisFault, it signals that something internal to the Axis autogen code failed. This could include your exception wrapped inside of it.
First, I want to address your pseudcode.
void method() throws AxisFault{....}
This pseudocode indicates that you want a method with no input, no output, but still have an exception. If I assume this, then that design is not recommended (I'm not even sure if it is possible). If you want something to trigger something to happen with no output, an empty output message is preferable to an exception. Exceptions should only be used when something uncommon happens.
If you meant the above code as an abstract example and you do have input/output, then the correct approach would be to make up your own fault. Using your own fault allows you to control behavior and more accurately describe what is failing. You may also need several faults in the future so using AxisFault is not beneficial in that case.
<wsdl:definitions ...>
...
<wsdl:message name="MyFault">
<wsdl:part name="parameters" element="def:MyFault">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="MyPortType">
<wsdl:operation name="doStuff">
<wsdl:input message="tns:MyRequest">
</wsdl:input>
<wsdl:output message="tns:MyResponse">
</wsdl:output>
<wsdl:fault name="MyFault" message="tns:MyFault">
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyBinding" type="tns:MyPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="doStuff">
<soap:operation soapAction="namespace/operationName"/>
<wsdl:input name="MyRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="MyResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="MyFault">
<soap:body use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
...
</wsdl:definitions>
That said, AxisFault does happen for web service operation calls. For your client stub code, it should throw a RemoteException. If you take a look at your autogen Stub code, you should see that does in fact throw an AxisFault which extends RemoteException.
using the faults
<definitions ...>
<message name="empty"/>
<message name="InsufficientFundsFault">
<part name="balance" type="xsd:int"/>
</message>
<portType name="Bank">
<operation name="throwException">
<input message="tns:empty"/>
<output message="tns:empty"/>
<fault name="fault" message="tns:InsufficientFundFault"/>
</operation>
</portType>
...
</definitions>

How to add custom SOAP-Header element to the generated WSDL in Spring-WS

we are migrating from WebLogic web-services to Spring-WS (1.5.X).
There is currently one issue we are facing:
We need to pass a context object (on WLS it is passed as SOAP-Header element) to other services that are still running on WLS from the Spring-WS powered service. The header element is still formulated on client side and the newly created WS (Spring-WS) should just pass it to other services.
I can imagine how the custom element would be passed: override the doWithMessage(WebServiceMessage message) method...
Is there a way to generate the wsdl with the help of DefaultWsdl11Definition to contain that custom header element?
See the example:
<wsdl:operation name="GetSomeInformation">
<soap:operation
soapAction="http://www.dummyservice.com/InformationService/GetSomeInformation" />
<wsdl:input>
<soap:body use="literal" />
<soap:header message="ctx:ServiceContextMessage" part="serviceContext" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
<wsdl:fault name="Error">
<soap:fault name="Error" use="literal" />
</wsdl:fault>
</wsdl:operation>
Thanks for help
We ran into a similar issue on my project. Check into extending SuffixBasedPortTypesProvider, SuffixBasedMessagesProvider, and Soap11Provider. We use the InliningXsdSchemaTypesProvider to import the schema we use to build the WSDL. If you run the WSDL generation through the debugger you'll get the hang of how it works. The Spring code is easy to follow and extend.

wsdl2java Error: Emitter failure. Invalid endpoint address in port

I am trying to run the wsdl2java command on a WSDL file that was given to me from another group in my company. I know wsdl2java works because I can run the examples but when I try it on the wsdl given to me it fails. The one big difference is that the WSDL given to me uses SSL.
I’m using Java 1.4 (checked it a few time) and made sure all the correct jars are in my class path, jsse.jar is there.
COMMAND: java org.apache.axis.wsdl.WSDL2Java --server-side GenericWebService.wsdl
ERROR:
log4j:WARN No appenders could be found for logger (org.apache.axis.i18n.ProjectResourceBundle).
log4j:WARN Please initialize the log4j system properly.
**java.io.IOException: Emitter failure. Invalid endpoint address in port AC_x0020_Generic_x0020_Web_0020_ServiceSoap in service AC_x0020_Generic_x0020_Web_x0020_ServiceLocator: **
at org.apache.axis.wsdl.toJava.JavaServiceImplWriter.writeFileBody(JavaServiceImplWriter.ja
a:242)
at org.apache.axis.wsdl.toJava.JavaWriter.generate(JavaWriter.java:127)
at org.apache.axis.wsdl.toJava.JavaServiceWriter.generate(JavaServiceWriter.java:112)
at org.apache.axis.wsdl.toJava.JavaGeneratorFactory$Writers.generate(JavaGeneratorFactory.j
va:421)
at org.apache.axis.wsdl.gen.Parser.generate(Parser.java:476)
at org.apache.axis.wsdl.gen.Parser.access$000(Parser.java:45)
at org.apache.axis.wsdl.gen.Parser$WSDLRunnable.run(Parser.java:362)
at java.lang.Thread.run(Thread.java:534)
asdf
<wsdl:portType name="AC_x0020_Generic_x0020_Web_x0020_ServiceSoap">
<wsdl:operation name="Provision">
<wsdl:input message="tns:ProvisionSoapIn" />
<wsdl:output message="tns:ProvisionSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="AC_x0020_Generic_x0020_Web_x0020_ServiceSoap" type="tns:AC_x0020_Generic_x0020_Web_x0020_ServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="Provision">
<soap:operation soapAction="http://xmlns.fmr.com/systems/dev/aar/2008/05/GenericWebService/Provision" style="document" />
<wsdl:input>
<soap:body use="literal" />
<soap:header message="tns:ProvisionServiceProcessingDirectives" part="ServiceProcessingDirectives" use="literal" />
<soap:header message="tns:ProvisionServiceCallContext" part="ServiceCallContext" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="AC_x0020_Generic_x0020_Web_x0020_Service">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Generic web service definition for provisioning requests callable by AccessCENTRAL</wsdl:documentation>
<wsdl:port name="AC_x0020_Generic_x0020_Web_x0020_ServiceSoap" binding="tns:AC_x0020_Generic_x0020_Web_x0020_ServiceSoap">
<soap:address location="" />
</wsdl:port>
</wsdl:service>
UPDATED SOLUTION:
The problem was that the parser needed a value in the <soap:address location="" /> for it to complete. I added the URL of my service and it worked.
New Lines looked like:
<soap:address location="" http://localhost:8080/axis/services/AC_x0020_Generic_x0020_Web_x0020_Service" />
The location specified by the soap:address is blank. It should be the URI of the SOAP service. See soap:address.
Looking at soapAction, http://xmlns.fmr.com/systems/dev/aar/2008/05/GenericWebService might be the correct value for location.

Categories

Resources