Consuming wsdl into spring boot

 Steps to consume SOAP wsdl into Spring Boot

1.       Create a standard spring boot project

2.       Copy the wsdl file content into <file-name>.wsdl file, saved in resources folder.

 https://apiservices.balady.gov.sa/v1/gsb/wasel-address-service


1.       In project window create an empty folders to store generated wsdl stub files.

Here, com.example.consumewebservice1.stubs  is the empty directory created.

1.       In pom.xml add dependencies spring web and spring web service and to convert WSDL to stub add jaxb plug-ins

<build>
    <plugins>
        <plugin>
            <groupId>
org.jvnet.jaxb2.maven2</groupId>
            <artifactId>
maven-jaxb2-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>
generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaLanguage>
WSDL</schemaLanguage>
                <generatePackage>
com.example.consumesoapwebservice1.stubs</generatePackage>
                <generateDirectory>
${project.basedir}/src/main/java</generateDirectory>
                <schemaDirectory>
${project.basedir}/src/main/resources/wsdl</schemaDirectory>
                <schemaIncludes>
                    <include>
*.wsdl</include>
                </schemaIncludes>
            </configuration>
        </plugin>
    </plugins>

 

${project.basedir} – it will get the project base directory, it is a spring boot feature.


1.       Execute mvn clean, mvn build/install commands, wsdl will get generated in stub directory.  Once you execute above commands following files will be generated in stub directory.


1.       To form a request object and call SOAP web service, below classes need to develop

-          Soap client

-          Bean config

2.       I named soap client file as WaselClient as per my project, soap client must extend WebSecurityGatewaySupport, by using in this file we will write logic to call soap webservice by passing url, request body, request header and getWebServiceTemplate() method marshalling will be done and retrieve the response. Below is my sample SoapClient/WaselClient file.

    1. Marhsalling is the process of converting java object into XML and unMarshalling is converting XML into java objects.
@Component
public class WaselClient extends WebServiceGatewaySupport {

   
@Autowired
   
SecurityHeader securityHeader;
   
@Autowired
   
GetToken getTokenClass;
   
@Autowired
    
WaselService waselService;

       public
GetIndividualWaselAddressResponse getIndividualAddress(String        url, Object request){
         
       String token = getTokenClass.getToken();
      
JAXBElement<GetIndividualWaselAddressResponse> res = null ; 
  SecurityHeader requestCallback = new SecurityHeader(token);
      
Object obj = getWebServiceTemplate().marshalSendAndReceive(url, request, requestCallback);
           GetIndividualWaselAddress requestbody = (GetIndividualWaselAddress) request;
           String identifier = requestbody.getIdentifier();
           waselService.saveAddress((GetIndividualWaselAddressResponse)obj, identifier);
       return (GetIndividualWaselAddressResponse)obj;
   }
}

1.       For BeanConfig.java, we can create separate class and annotate with @Configuration or else we can add below lines into our mainClass.java after main method.

  @Autowired

    WaselClient client;


    @Bean

    public Jaxb2Marshaller marshaller()  {

        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();

        marshaller.setContextPath("com.example.consumesoapwebservice1.stubs");

        return marshaller;

    }

    @Bean

    public WaselClient soapConnector(Jaxb2Marshaller marshaller) {

//        WaselClient client = new WaselClient();

        client.setDefaultUri("https://apiservices.balady.gov.sa/v1/gsb/wasel-address-service");

        client.setMarshaller(marshaller);

        client.setUnmarshaller(marshaller);

        return client;

    }


1.       Create a controller to for REST API,

-          Now, below controller will make a call to SOAP webservice, objectFactory will help to create request body.

-          waselClient.getIndividualAddress() is the method created in wasel client/soap client, it will accept url and request body

For e.g., 

@RestController
public class WaselController {

   
@Autowired
   
WaselClient waselClient;

   
@GetMapping("/getIndividualAddress/{nationalId}")
   
public GetIndividualWaselAddressResponse getIndividualAddress(@PathVariable String nationalId) {
       
ObjectFactory objectFactory = new ObjectFactory();
        GetIndividualWaselAddress requestBody = objectFactory.createGetIndividualWaselAddress();

        if(nationalId.startsWith("1")){
            requestBody.setIdentifierType(ItemChoiceType.
NATIONAL_ID);
       
}
       
if(nationalId.startsWith("2")){
            requestBody.setIdentifierType(ItemChoiceType.
IQAMA_NUMBER);
        
}
        requestBody.setIdentifier(nationalId);
       
GetIndividualWaselAddressResponse individualAddressResponse = waselClient.getIndividualAddress("https://apiservices.balady.gov.sa/v1/gsb/wasel-address-service", requestBody);

        return individualAddressResponse;
   
}
}


1.       To pass custom request header in soap webservice, we have to create a SecurityHeader class that implements WebServiceMessageCallback interface and override doWithMessage() method to pass custom headers as shown below.

@Component
public class SecurityHeader implements WebServiceMessageCallback {

   String
oAuthToken;
 
public SecurityHeader(String oAuthToken) {
   
this.oAuthToken = oAuthToken;
}

public SecurityHeader( ) {
  
super();
}
@Override
   
public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
      t
ry {
      
    if (message instanceof SaajSoapMessage) {
              SaajSoapMessage soapMessage = (SaajSoapMessage) message
;
              
MimeHeaders mimeHeader = soapMessage.getSaajMessage().getMimeHeaders();
              mimeHeader.setHeader("Authorization", this.oAuthToken);
              
mimeHeader.setHeader("Content-Type", "text/xml");
               
mimeHeader.setHeader("SOAPAction","http://tempuri.org/IWaselAddressService/GetIndividualWaselAddress");
           
}
        }
catch (Exception e) {
           
throw new RuntimeException(e);
       
}

    }
}
       If we have more than 1-method in single webservice, then in set required header SOAPAction parameter. To pass any customized headers we have to do this all in doWithMessage() method.

================================================================
1.       This is exceptional case, not related to consuming wsdl in spring boot. In above application I have to pass authorization token generated by some other rest api into soap webservice. So to get token from remote rest api, I used openFeign to call it. Next slides will demonstrate you the same.

@FeignClient(url="https://apiservices.balady.gov.sa", value = "wasel-feign-client", path = "/oauth/v1", configuration = CoreFeignConfiguration.class)
public interface AccessTokenFiegnClient {

   
@RequestMapping(value = "/token", method = RequestMethod.POST, consumes = APPLICATION_FORM_URLENCODED_VALUE)
    ResultData
getToken(@RequestHeader("authorization") String authorization, @RequestHeader("content-type") String contentType
           
, @RequestHeader("cache-control") String cacheControl, @RequestBody Map<String, ?> form);

}


@Component

public class GetToken {


    @Autowired

    AccessTokenFiegnClient accessTokenFiegnClient;


    public String getToken() {

        System.out.println("In GetToken >>> getToken");


        String authorization = "Basic QlluNXBaZms5Uzk3SDU0RkNpR1hFcnFsQTFBaEFnNHg6bkM3V3JBeDU0REd3SmJHQQ==";

        String contentType ="application/x-www-form-urlencoded";

        String cacheControl = "no-cache";

        Map<String, String> form = new HashMap<>();

        form.put("grant_type","client_credentials");

        ResultData data = accessTokenFiegnClient.getToken(authorization, contentType, cacheControl, form);

        System.out.println("Access_token >> " + data.getAccess_token());

        return "Bearer "+data.getAccess_token();

    }


    public GetToken() {

    }
}



*******Alhamdulillah*********









 

Comments

Popular posts from this blog

Spring Interview Preparation

Git-hub handy code