Reputation:
I am using open-jdk 11 and spring boot version 2.3.0.RELEASE. I am new to soap web services and i want to try do a test with soap producer sample. Below is the link of wsdl that I am trying to consume: http://www.thomas-bayer.com/axis2/services/BLZService?wsdl
I added the following plugin in the pom.xml for generating the classes from wsdl:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>soapws.credins.api</generatePackage>
<generateDirectory>${project.basedir}/src/main/java</generateDirectory>
<schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory>
<schemaIncludes>
<include>*.wsdl</include>
</schemaIncludes>
<clearOutputDir>true</clearOutputDir>
</configuration>
</plugin>
Then i run a mvn install
and all the classes were generated successfully. I created a bean Jaxb2Marshaller
for converting from java classes to xml. Below it is the implementations:
@Configuration
public class SoapConfiguration {
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("package.api");
return marshaller();
}
}
After that I have created a client class which makes the soap calls like below:
@Component
public class BankClient {
@Autowired
private Jaxb2Marshaller marshaller;
private WebServiceTemplate template;
public DetailsType getBankDetails(String blz) {
GetBankType request = new GetBankType();
request.setBlz(blz);
template = new WebServiceTemplate(marshaller);
DetailsType detail = (DetailsType) template
.marshalSendAndReceive("http://www.thomas-bayer.com/axis2/services/BLZService", request);
return detail;
}
}
I had a problem when executing the call :
org.springframework.oxm.MarshallingFailureException: JAXB marshalling exception; nested exception is javax.xml.bind.MarshalException
- with linked exception:
I fixed this issue by adding the @XmlRootElement
to GetBankType
class like below:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getBankType", propOrder = {
"blz"
})
public class GetBankType {
@XmlElement(required = true)
protected String blz;
/**
* Gets the value of the blz property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getBlz() {
return blz;
}
/**
* Sets the value of the blz property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setBlz(String value) {
this.blz = value;
}
}
Now I am stuck with this problem: I am not able to figure out where the problem is.
org.springframework.ws.soap.client.SoapFaultClientException: The endpoint reference (EPR) for the Operation not found is http://www.thomas-bayer.com/axis2/services/BLZService and the WSA Action =
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
at soapws.client.BankUpClient.getBankDetails(BankUpClient.java:26)
What am I doing wrong
Upvotes: 0
Views: 3952
Reputation: 1522
First remove the @XmlRootElement
from the generated classes in package package.api
.
Next modify BankClient
like below:
@Component
public class BankClient {
@Autowired
private Jaxb2Marshaller jaxb2Marshaller;
private WebServiceTemplate template;
public JAXBElement<GetBankResponseType> getBankDetails(String blz) {
GetBankType getBankType = new GetBankType();
getBankType.setBlz(blz);
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<GetBankType> request = objectFactory.createGetBank(getBankType);
template = new WebServiceTemplate(jaxb2Marshaller);
JAXBElement<GetBankResponseType> response = (JAXBElement<GetBankResponseType>) template
.marshalSendAndReceive("http://www.thomas-bayer.com/axis2/services/BLZService", request);
return response;
}
}
To build the request you need to use the class ObjectFactory
that was autogenerated from WSDL.
ObjectFactory
class allows us to programmatically construct request from java objects that will represent XML content.
Next thing to keep in mind, that also the response that you will get from the WebServiceTemplate
is going GetBankResponseType
wrapped inside a representation of XML content.
GetBankResponseType
is going to be an object that will contain the content model and attribute values of the information we receive from the soap.
Below is an integration test for the BankClient:
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class BankClientTest {
@Autowired
private BankClient client;
@BeforeEach
public void setup() {
}
@Test
void testGetBankDetails() {
// setup
String blzCode = "39580041";
String bezeichnungExpected = "Dresdner Bank";
String bicExpected = "DRESDEFF395";
String ortExpected = "Düren, Rheinl";
String plzExpected = "52304";
// execute
JAXBElement<GetBankResponseType> response = client.getBankDetails(blzCode);
// verify
assertEquals(bezeichnungExpected, response.getValue().getDetails().getBezeichnung());
assertEquals(bicExpected, response.getValue().getDetails().getBic());
assertEquals(ortExpected, response.getValue().getDetails().getOrt());
assertEquals(plzExpected, response.getValue().getDetails().getPlz());
}
}
Upvotes: 2