In this post, I am going to show/teach you how to use SOAP-based web services to populate JavaFX Gridpane but first we have to create/expose the webservice. This is a continuation of the tutorial/project on Car Rental Enterprise Application.

Web services are based on the exchange of messages using non-proprietary protocol messages. The messages themselves are not sufficient to define the web service platform. We actually need a list of standard components, including the following:

  • A language used to define the interfaces provided by a web service in a manner that
    is not dependent on the platform on which it is running or the programming language
    used to implement it
  • A common standard format to exchange messages between web service providers
    and web service consumers
  • A registry within which service definitions can be placed

The Web Service Description Language, also known as WSDL (http://www.w3.org/TR/wsdl) is the de facto standard to provide a description of a web service contract exposed to clients. In particular, a WSDL document describes a web
service in terms of the operations that it provides, and the data types that each operation
requires as inputs and can return in the form of results.
Communication between the service provider and service consumer happens by means of
XML messages that rely on the SOAP specification.
A basic SOAP message consists of an envelope that may contain any number of headers
and a body. These parts are delimited by XML elements called envelope, header, and
body, which belong to a namespace defined by the SOAP specification.

Wildfly SOAP-based Web service Stack

All JAX-WS functionalities provided on top of WildFly are currently served through a
proper integration of the JBoss web services stack with most of the Apache CXF project.
Apache CXF is an open source web service framework that provides an easy-to-use,
standard-based programming model to develop both SOAP and REST web services. The
integration layer (JBossWS-CXF in short hereafter) allows us to perform the following:
Use standard web services APIs (including JAX-WS) on a WildFly Application
Server; this is performed internally by leveraging Apache CXF, without requiring the
user to deal with it
Leverage Apache CXF’s advanced native features on top of a WildFly Application
Server without the need for the user to deal with all the required integration steps to
run the application in such a container
Therefore, the focus of the next section will be on developing JAX-WS web services using
the built-in Apache CXF configuration. If you want to further expand your knowledge
about Apache CXF’s native features.

When a SOAP message sent by the client enters the web service runtime environment, it is
captured by a component named server endpoint listener, which, in turn, uses the
Dispatcher module to deliver the SOAP message to that service.
At this point, the HTTP request is converted internally into a SOAP message. The message
content is extracted from the transport protocol and processed through the handler chain
configured for the web service.
SOAP message handlers are used to intercept SOAP messages as they make their way
from the client to the endpoint service and vice versa. These handlers intercept SOAP
messages for both the request and response of the web service.
The next step is unmarshalling the SOAP message into Java objects. This process is
governed by WSDL to Java Mapping and XML to Java Mapping. The former is performed
by the JAX-WS engine, and it determines which endpoint to invoke from the SOAP
message. The latter, performed by the JAXB libraries, deserializes the SOAP message so
that it is ready to invoke the endpoint method.
Finally, the deserialized SOAP message reaches the actual web service implementation
and the method is invoked.
Once the call is completed, the process is reversed. The return value from the web service
method is marshalled into a SOAP response message using JAX-WS WSDL to Java
mapping and JAXB 2.0 XML to Java mapping.
Note
The JAXB provides a fast and convenient way to bind XML schemas and Java
representations, making it easy for Java developers to incorporate XML data and process
functions in Java applications. As part of this process, JAXB provides methods to
unmarshal XML instance documents into Java content trees, and then marshal Java
content trees back into XML instance documents. JAXB also provides a way to generate
XML schema from Java objects.
Next, the outbound message is processed by handlers before returning it to the dispatcher
and endpoint listener that will transmit the message as an HTTP response.

We shall be exposing the Session Bean class we created earlier in this POST as a webservice by decorating it with some annontations. The annotations are:

  • @WebService; This annotation simples turns a Java class into a web service but in our case, it exposes the Session bean as a Web service. Inside it, we specify our serviceName.  The name specified using serviceName is used to generate the name attribute in the service element in the WSDL interface. If you don’t specify the serviceName element, the server will generate it using the default value, which is the bean class name appended with the service.  you can also specify additional elements, such as the targetNamespace element that declares the namespace used for the WSDL elements generated by the web service. If you don’t specify this element, the web service container will use the Java package name to generate a default XML namespace.
  • @WebMethod;  Attaching the @WebMethod attribute to a public method indicates that you want the method exposed as part of the web service.
  • @WebParam;  The @WebParam annotation is used to specify the parameter’s name that needs to be exhibited in the WSDL. You should always consider using a WebParam annotation, especially when using multiple parameters, otherwise the WSDL will use the default argument parameter (in this case, arg0), which is meaningless for web service consumers.
  • @WebResult;  The @WebResult annotation is quite similar to @WebParam in the sense that it can be used to specify the name of the value returned by the WSDL.
  • @SOAPBinding;  We state that the web service is of the type Remote Procedure Call using the @javax.jws.SOAPBinding annotation. The possible values are DOCUMENT and RPC, the first one being the default value.
    Note
    The choice between the RPC and Document style boils down to the different ways we can
    construct services using these two styles. The body of an RPC-style SOAP message is
    constructed in a specific way, which is defined in the SOAP standard. This is built on the
    assumption that you want to call the web service just like you would call a normal
    function or method that is part of your application code.
    Therefore, the RPC is more tightly coupled because if you make any changes in the
    message structure, you’ll need to change all the clients and servers processing this kind of
    message.
    A document-style web service, on the other hand, contains no restrictions for how the
    SOAP body must be constructed. It allows you to include whatever XML data you want
    and also a schema for this XML. Therefore, the document style is probably more flexible,
    but the effort to implement the web service and clients may be slightly more.
    In the end, the likelihood of change is a factor that one has to consider when choosing
    whether to use RPC- or Document-style web services.
package com.rental.bean;


/**
 *
 * @author STEINACOZ-PC
 */
@Stateless
@WebService(serviceName="rentalWS")
public class rentalBean implements rentalRemote{

    public rentalBean() {
    }
    

    @WebMethod(operationName="allCars")
    @Override
    public List<Info> carStatus() {
return em.createQuery("From Info").getResultList();
    }

    @WebMethod
    @Override
    public void search(String ref) {
        Info inf;
        
     Query q = em.createNamedQuery("Info.findByRef");
     q.setParameter("ref", ref);
    
     inf = (Info) q.getSingleResult();
     
     setCaName(inf.getCarname());
     setCaModel(inf.getCarmodel());
     setCaPrice(inf.getPrice());
     setCaCategory(inf.getCategory());
     setCaYear(inf.getYear());
     setCaImg(inf.getImage());
     setCarAvail(inf.getAvailable());
     setCarCarExpectDate(inf.getExpecteddate());
     
    }
    
   
    
}

For the full source code of the EJB Module, refer to this POST or my github Page.

After the decoration, redeploy the EJB Module and watch the server console for this outputs:

19:15:12,106 INFO  [org.infinispan.configuration.cache.EvictionConfigurationBuilder] (ServerService Thread Pool -- 76) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
19:15:12,108 INFO  [org.infinispan.configuration.cache.EvictionConfigurationBuilder] (ServerService Thread Pool -- 76) ISPN000152: Passivation configured without an eviction policy being selected. Only manually evicted entities will be passivated.
19:15:12,113 INFO  [org.jboss.ws.cxf.metadata] (MSC service thread 1-1) JBWS024061: Adding service endpoint metadata: id=rentalBean
 address=http://localhost:8050/CarRental-ejb/rentalWS/rentalBean
 implementor=com.rental.bean.rentalBean
 serviceName={http://bean.rental.com/}rentalWS
 portName={http://bean.rental.com/}rentalBeanPort
 annotationWsdlLocation=null
 wsdlLocationOverride=null
 mtomEnabled=false
19:15:12,181 INFO  [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 76) WFLYCLINF0002: Started client-mappings cache from ejb container
19:15:12,209 INFO  [org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-1) Creating Service {http://bean.rental.com/}rentalWS from class com.rental.bean.rentalBean
19:15:13,104 INFO  [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-1) Setting the server's publish address to be http://localhost:8050/CarRental-ejb/rentalWS/rentalBean
19:15:13,279 INFO  [org.jboss.ws.cxf.deployment] (MSC service thread 1-1) JBWS024074: WSDL published to: file:/C:/wildfly-10/standalone/data/wsdl/CarRental-ejb.jar/rentalWS.wsdl
19:15:13,357 INFO  [org.jboss.as.webservices] (MSC service thread 1-2) WFLYWS0003: Starting service jboss.ws.endpoint."CarRental-ejb.jar".rentalBean
19:15:13,445 INFO  [org.jboss.as.jpa] (ServerService Thread Pool -- 76) WFLYJPA0010: Starting Persistence Unit (phase 2 of 2) Service 'CarRental-ejb.jar#CarRental-ejbPU'
19:15:13,458 INFO  [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 76) HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL94Dialect
19:15:13,562 INFO  [org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl] (ServerService Thread Pool -- 76) HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
19:15:13,573 INFO  [org.hibernate.type.BasicTypeRegistry] (ServerService Thread Pool -- 76) HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType@79ab859e
19:15:13,579 INFO  [org.hibernate.envers.boot.internal.EnversServiceImpl] (ServerService Thread Pool -- 76) Envers integration enabled? : true
19:15:13,748 INFO  [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator] (ServerService Thread Pool -- 76) HHH000397: Using ASTQueryTranslatorFactory
19:15:14,339 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 76) WFLYUT0021: Registered web context: /CarRental-ejb

 

Lines 3-16 are the most important information here. For example, the first line states that the web service has been bound in the endpoint registry as

serviceName={http://bean.rental.com/}rentalWS

Next is the information about the web context path, which, by default, has the same name as your project, that is, CarRental-ejb

19:15:14,339 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 76) WFLYUT0021: Registered web context: /CarRental-ejb

. The last piece of information is about the web service address, which is

address=http://localhost:8050/CarRental-ejb/rentalWS/rentalBean

By appending the ?wsdl suffix to the end of the address, you can inspect the web service contract.

ws3
Note
The data directory contains a versioned list of all the generated WSDLs. So, you might
find the entire history of your web services published by ticket-agency-ws in
JBOSS_HOME/standalone/data/wsdl/CarRental-ejb.jar.
Inspecting the web service from the console
You can inspect the web services subsystem by moving to the web admin console and
navigating to Runtime | Status | Subsystems | Web Services.
Here, you can gather some useful information about the services deployed. In fact, the
most useful option is the list of endpoint contracts available, which is needed when
developing our clients. The following screenshot shows a view of the web service
endpoints from the console:

soap webservices - geekshelm

In the next post, we shall be creating the JavaFX GUI that will consume the web service.

LEAVE A REPLY

Please enter your comment!
Please enter your name here