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
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 Implementation – ClientTransactionImpl 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 🙂