user12827457
user12827457

Reputation:

Consuming SoapWeb Services with Spring Boot not working?

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

Answers (1)

Rando Shtishi
Rando Shtishi

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

Related Questions