SOAP – Invoking Web Services Without Using the WSDL File. [JAX-WS & Apache CXF]

Through this article I will guide you through the steps for developing a sample web services client application and a server (SOAP) and tips for how to invoke web services without using the WSDL File. Think you have the basic understanding of SOAP web services and the WSDLs.

Overview

Jax-WS

Following are some of the key things we are going to use throughout this article.

1) JAX-WS [Java API for XML Web Services]
A set of APIs for creating web services in XML format (SOAP).JAX-WS provides many annotation to make the development on both web service client and servers in a simple and an effective manner.

2) Apache CXF
Apache CXF is a framework that helps to develop services using JAX-WS APIs.

3) Configure secure transaction for HTTPS Requests using javax.net.ssl.TrustManager

This article cover following sections.

1) Developing a SOAP-based Document style web service endpoint by using JAX-WS API.

When creating web services using SOAP protocol, we have to follow,

  • RPC messaging style                                                                                                                                                                                                                   SOAP message body contains an XML representation of a method call and uses the names of the method and its parameters to generate XML structures that represent a method’s call stack.
  • Document messaging style                                                                                                                                                                                                      The SOAP body contains a XML document which can be validated against pre-defined XML schema document.

Here we are using document messaging style.

Server

1) Creating Web Service Endpoint Interface – ClientTransaction Interface

 import javax.jws.WebMethod;
 import javax.jws.WebService;
 import javax.jws.soap.SOAPBinding;
 import javax.jws.soap.SOAPBinding.Style;
 import javax.jws.soap.SOAPBinding.Use;

@WebService
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL)

public interface ClientTransaction {

@WebMethod String getOrderDetails(String orderNo);

}

2) Creating Web Service Endpoint ImplementationClientTransactionImpl Class

import com.expr.ws.server.controller.ClientTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jws.WebService;


@WebService(endpointInterface = "com.expr.ws.server.controller.ClientTransaction")
public class ClientTransactionImpl implements ClientTransaction {

    private static final Logger logger = LoggerFactory.getLogger(ClientTransactionImpl.class);

    @Override
    public String getOrderDetails(String orderNo) {
        logger.debug("Received Order No : [{}]", orderNo);
        return "Paid Amount 25.00 LKR | Transaction Ref No - 25669321  for order No - " + orderNo;
    }

}

3) Configure Server Endpoint
Apache CXF JAX-WS configurations used as server configurations.

expr_ws_config.xml

<bean id="exprWsServer" class="com.expr.ws.server.controller.impl.ClientTransactionImpl">
 </bean>
<jaxws:endpoint id="exprWsUrl" address="${service.url}">
 <jaxws:implementor>
 <ref local="exprWsServer"/>
 </jaxws:implementor>
 </jaxws:endpoint>

 

4) Run the Application – Starter.java

ApplicationContext context = new ClassPathXmlApplicationContext("expr_ws_config.xml");

Running Server

1) Build app from home directory

 Run - mvn clean install

2) Run app

Unzip - unzip /target/jax-ws-app.zip
Go to - /jax-ws-app/bin
Run   - ./startServer console

3) Verify

Access URL to
http://127.0.0.1:65024/exprws?wsdl

You can download the Sample Application from Github

Client

1) Creating Client – ExprWsClient.java

import com.expr.ws.server.controller.ClientTransaction;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;

public class ExprWsClient extends AbstractSecureWsHandler {

    private static final Logger logger = LoggerFactory.getLogger(ExprWsClient.class);
    private static final String SERVICE_URL = "http://127.0.0.1:65024/exprws";

    public static void main(String[] args) throws Exception {

        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(ClientTransaction.class);
        factory.setAddress(SERVICE_URL);
        ClientTransaction clientTransaction = (ClientTransaction) factory.create();

        Client client = ClientProxy.getClient(clientTransaction);
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor());

        // Configure secure services for HTTPS
        configureSecureTransaction(clientTransaction);

        // Request for Order Details
        String orderDetails = clientTransaction.getOrderDetails("445677");
        logger.debug("Result : [{}]", orderDetails);

    }


}

As in the above code JaxWsProxyFactoryBean factory created to avoid invoking the web services using the WSDL File. SERVICE_URL – used according to the server we configured.

2) Enable service for HTTPS Requests – AbstractSecureWsHandler.java

import com.expr.ws.server.controller.ClientTransaction;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public abstract class AbstractSecureWsHandler {

    private static final Logger logger = LoggerFactory.getLogger(AbstractSecureWsHandler.class);

    /**
     * Enable Services for HTTPS Requests
     * @param clientTransaction
     */
    public static void configureSecureTransaction(ClientTransaction clientTransaction) {
        Client client = ClientProxy.getClient(clientTransaction);
        HTTPConduit http = (HTTPConduit) client.getConduit();
        String targetAddress = http.getTarget().getAddress().getValue();
        logger.info("Received Target Address [{}]", targetAddress);

        if (targetAddress.toLowerCase().startsWith("https:")) {
            logger.info("Execute TrustManager for  HTTPS");
            TrustManager[] simpleTrustManager = new TrustManager[] { new X509TrustManager() {
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] certs, String authType) {
                }
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            } };
            TLSClientParameters tlsParams = new TLSClientParameters();
            tlsParams.setTrustManagers(simpleTrustManager);
            tlsParams.setDisableCNCheck(true);
            http.setTlsClientParameters(tlsParams);
        }
    }

}

As stated above javax.net.ssl.TrustManager used to accept HTTPS requests and handle them without causing any issue.

Okay! So we are almost done in the development of Client for our Web service. You can test it by just running the ExprWsClient.java.

You will get the following result as per your configuration if you succeeded.

Result : Paid Amount 25.00 LKR | Transaction Ref No - 25669321  for order No - 445677

You can download the Sample Application from Github

So think it is helpful and please let me know if you any clarifications or details.

Happy Coding 🙂

Blog Stats

  • 38,691 hits