We have an example WSDL that has been provided by an API provider and we want to integrate with it.
I tried the provided example at https://spring.io/guides/gs/consuming-web-service/
and some other .wsdl files and it all looks good.
In my case with my wsdl - when running the command to generate the classes - only some of them are generated, but not all of them.
This is not the case in SoapUI - all is good there.
Any info why this is happening?
My pom.xml is the following
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.13.2</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>com.test.xxx.soapclient.generated</generatePackage>
<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.wsdl</include>
</schemaIncludes>
</configuration>
</plugin>
</plugins>
</build>
What i have come to see is that only the complex types
are being created as classes - while the others are not.
In my example the input message is the one below and no classes are being generated for it.
How can i do that?
Also what is interesting here is - soapAction
has empty string as parameter - and Java's API requires SoapAction
Java Code
public Object callWebService(String action, Object request){
return getWebServiceTemplate().marshalSendAndReceive(request,new SoapActionCallback(action));
}
Actual WSDL File
<operation name="login" parameterOrder="user password">
<input message="tns:CardManagementEP_login"> </input>
<output message="tns:CardManagementEP_loginResponse"> </output>
</operation>
<message name="CardManagementEP_loginResponse">
<part name="result" type="xsd:string"> </part>
</message>
<message name="CardManagementEP_login">
<part name="user" type="xsd:string"> </part>
<part name="password" type="xsd:string"> </part>
</message>
<operation name="login">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" namespace="http://com.tch.cards.service"/>
</input>
<output>
<soap:body use="literal" namespace="http://com.tch.cards.service"/>
</output>
</operation>
I managed to resolve the issue with the help of DaShaun Carter from the show Spring Office Hours.
The issue was that the above mentioned WSDL file was really old, so the classes for requests/responses which are not complex were not generated.
What we did is modify the existing WSDL and create these things as complex types - so Jaxb will generate classes for them
example-wsdl.wsdl
<complexType name="login">
<sequence>
<element name="user" type="string"/>
<element name="password" type="string"/>
</sequence>
</complexType>
<complexType name="loginResponse">
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
After that, the classes are getting generated, but they did not work for me, and i had to some manual changes in order to get them working
LoginResponse.java
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "loginResponse", namespace = "http://com.tch.cards.service")
@XmlAccessorType(XmlAccessType.FIELD)
public class LoginResponse {
@XmlElement(required = true)
protected String result;
public String getResult() {
return result;
}
public void setResult(String value) {
this.result = value;
}
}
Login
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "login", namespace = "http://com.tch.cards.service")
@XmlAccessorType(XmlAccessType.FIELD)
public class Login {
@XmlElement(required = true)
protected String user;
@XmlElement(required = true)
protected String password;
public String getUser() {
return user;
}
public void setUser(String value) {
this.user = value;
}
public String getPassword() {
return password;
}
public void setPassword(String value) {
this.password = value;
}
}
Also, in my case, the Soap Action did not matter, and i am passing empty strings.
The code where the actual calls were happening is as follows:
Login login = new Login();
login.setUser("user");
login.setPassword("password");
LoginResponse response = (LoginResponse) soapConnector.callWebService("", login);
System.out.println(response);
IMPORTANT NOTE: Change the namespace as per usecase - this is really important