Web Service Introduction
1. Introduction
1.1 Web Service Concept
A Web Service is a software application that is available over the Internet, which is accessible through standard-based Internet protocols such as HTTP.
The main purpose of Web service technologies is to allow applications on different platforms (including different software language, different operating system, different hardware) to exchange business data. Web services are widely used for EAI and B2B communication.
To achieve the capability of two different software applications to interoperate, some major technologies are used: TCP/IP, DNS, and HTTP, and the Web service standards: XML, SOAP, WSDL, and UDDI.
1.2 Rest And SOAP Web Service
On a technical level, web service can be implemented in various ways, the two most popular ways are SOAP based web service and Restful web service.
SOAP(Simple Object Access Protocol) is the standard xml labguage defining message architecture and message formats , the latest version is 1.2, you can refer to SOAP if you would like to know more about SOAP. This kind of web service always requires a description document of operations offered by the service, written in the Web Services Description Language (WSDL), refer to WSDL for more detail.
REST is a style of software architecture, it defines several constraints to the software architecture, while leaing the implementation of individual components free to design. A Restful web service mainly uses existing well-known W3C and Internet Engineering Task Force (IETF) standards (HTTP, XML, URI, MIME), it is a lightweight infrastructure and easy to get start.
A SOAP-based design must include the following elements.
-
A formal contract must be established to describe the interface that the web service offers. WSDL can be used to describe the details of the contract, which may include messages, operations, bindings, and the location of the web service. You may also process SOAP messages in a JAX-WS service without publishing a WSDL.
-
The architecture must address complex nonfunctional requirements. Many web service specifications address such requirements and establish a common vocabulary for them. Examples include transactions, security, addressing, trust, coordination, and so on.
-
The architecture needs to handle asynchronous processing and invocation. In such cases, the infrastructure provided by standards, such as Web Services Reliable Messaging (WSRM), and APIs, such as JAX-WS, with their client-side asynchronous invocation support, can be leveraged out of the box.
A RESTful design may be appropriate when the following conditions are met.
-
The web services are completely stateless. A good test is to consider whether the interaction can survive a restart of the server.
-
A caching infrastructure can be leveraged for performance. If the data that the web service returns is not dynamically generated and can be cached, the caching infrastructure that web servers and other intermediaries inherently provide can be leveraged to improve performance. However, the developer must take care because such caches are limited to the HTTP GET method for most servers.
-
The service producer and service consumer have a mutual understanding of the context and content being passed along. Because there is no formal way to describe the web services interface, both parties must agree out of band on the schemas that describe the data being exchanged and on ways to process it meaningfully. In the real world, most commercial applications that expose services as RESTful implementations also distribute so-called value-added toolkits that describe the interfaces to developers in popular programming languages.
-
Bandwidth is particularly important and needs to be limited. REST is particularly useful for limited-profile devices, such as PDAs and mobile phones, for which the overhead of headers and additional layers of SOAP elements on the XML payload must be restricted.
-
Web service delivery or aggregation into existing web sites can be enabled easily with a RESTful style. Developers can use such technologies as JAX-RS and Asynchronous JavaScript with XML (AJAX) and such toolkits as Direct Web Remoting (DWR) to consume the services in their web applications. Rather than starting from scratch, services can be exposed with XML and consumed by HTML pages without significantly refactoring the existing web site architecture. Existing developers will be more productive because they are adding to something they are already familiar with rather than having to start from scratch with new technology.
In our current
practical arena, it is enough to use Restful web service, but may
change to use SOAP when consideraing the security.
1.3 JAX-RS and CXF
JAVA EE provides
JAX-RS
API to make it easy to develop applications that use the REST
architecture, it uses Java programming language annotations to
simplify the development of RESTful web services.
There are various impmentations of JAX-RS, we have chooen the Apache CXF, as it implements both JAX-WS and JAX-RS. We can switch between JAX-WS and JAX-RS easily.
2. Server Side Develop
The server side develop is based on the Apache CXF's implementation of JAX-RS
2.1 Environment Set Up
2.1.1 the version of the CXF
2.6.1
2.1.2 the dependencies needed
The depended lib are listed below
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-bundle-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.0</version>
</dependency>
2.2 Service Implementation
2.2.1 Define Resource Class
A resource class is a Java class annotated with JAX-RS annotations to represent a Web resource. A resource class is annotated with at least a @Path annotation.
@Path(value = "/")
@Produces("application/xml;charset=UTF-8")
@Consumes("application/xml")
publicinterface RestService
The @Produces annotation is used to specify the format of the response.
The
@Consumes annotation is used to specify the format of the request.
We have defined an interface for Restful resource class named RestService. Developers which develop other Restful web service based on JAX-RX can just implement this interface. Do not need to care about the annotations configuration, but based on the business implementation.
e.g.
publicclass SOFS2AFSARestImpl implements RestService
2.2.2 Define the HTTP method
The JAX-RS specification defines a number of annotations such as @GET, @PUT, @POST and @DELETE.
@POST
@Path(value="/post")
Response
post(Message message);
@GET
@Path(value="/get")
Response get(@QueryParam("key")String key);
when there is annotation @POST on the method post(), means the HTTP POST action will match this method.
The @Path can also be
applied to method, when not defined the path for the method, then it
is just inherited from the resource class.
The Service
implementation class can override the annotations configure of the
Interface defined.
2.2.3 Return Type
Either javax.ws.rs.core.Response or custom type can be returned. javax.ws.rs.core.Response can be used to set the HTTP response code, headers and entity.
Our common interface use the javax.ws.rs.core.Response as return type.
2.3 Handle Data Bindings
JAX-RS
MessageBodyReader and MessageBodyWriter can be used to create data
bindings for reading and writing data in a number of different
formats. CXF supports various data bindings framework, it default
uses JAXB as the XML data binding.
2.3.1 JAXB Default Data Binding
To tell the JAXB how Java objects can be serialized to XML, the simplest way is to mark a given type with
@XmlRootElement annotation.
@XmlRootElement(name="Shipment")
@XmlSeeAlso({WsControl.class,Transaction.class,Login.class,Mesg.class,User.class,Entry.class})
@XmlType
publicclass Message
the @XmlRootElement is primarily used to specify the root object, This is so when your JAXB implementation begins unmarshalling an XML document it knows what object to instantiate.
The
@XmlType refers to a complex type name, compared to @XmlRootElement,
@XmlType can also specify the property order,
@XmlType(propOrder={"foo",
"bar"}
we have defined a common Interface in our Web Service framework. Including the standard XML request/response format and the corresponding JAXB annotated Java Beans.
2.3.2 Customized Data Binding
JAXB does not support the Java HashMap type bindings, so we have defined customized HashMap type adaptor, which can marshal/unmarshal between XML and HashMap.
Developers
just use the common Interface as the interchanging data format, then
no need to do additional implementation.
2.4 Dealing With Interceptors
CXF supports an Inbound Interceptor chain and an Outbound Interceptor chain. When a service is invoked, an InterceptorChain is created and invoked. Each interceptor gets a chance to do what they want with the message. This can include reading it, transforming it, processing headers, validating the message, etc.
In our Web Service framework, we have defined several Interceptors to handle the request message.
Translation Interceptor is one of them added into the Inbound Interceptor chain to translate various message format to our standard XML request format.
publicabstractclass MessageTranslationInterceptor extends AbstractPhaseInterceptor<Message>
publicclass XSLTranslationInterceptor extends MessageTranslationInterceptor
publicclass CrossTranslationInterceptor extends MessageTranslationInterceptor
Developers
only need to configure the Interceptors needed refering section 2.5
Spring configurations.
2.5 Configure In Spring
CXF has integrated with Spring perfectly, JAX-RS services can be configured using Spring conveniently.
<!-- defines the Interceptor for XSLT translation -->
<beanid="xslTranslationInterceptor"class="com.icil.service.web.interceptor.XSLTranslationInterceptor">
<propertyname="mappingFilePathName">
<map>
<entrykey="0"value="/opt/XSLTranslator/mappingfile/BaseBookingInfo.xsl"/>
</map>
</property>
<propertyname="dataSourceFilePath"value="/opt/XSLTranslator"/>
<propertyname="translatedFilePath"value="/opt/XSLTranslator"/>
</bean>
<!-- defines the Interceptor for CrossTranslator translation -->
<beanid="crossTranslationInterceptor"class="com.icil.service.web.interceptor.CrossTranslationInterceptor">
<propertyname="mappingFilePathName">
<map>
<entrykey="0"value="/opt/CrossTranslator/mapping_script/BookingTransfer/sofs_xml_afsa_xml_v25.cmp"/>
</map>
</property>
<propertyname="idForDataSourceFile">
<map>
<entrykey="0"value="21671"/>
</map>
</property>
<propertyname="dataSourceFilePath"value="/opt/CrossTranslator/data/BookingTransfer"/>
<propertyname="idForTranslatedFile">
<map>
<entrykey="0"value="22114"/>
</map>
</property>
<propertyname="translatedFilePath"value="/opt/CrossTranslator/data/BookingTransfer"/>
<propertyname="translateLogFilePath"value="/tmp"/>
<propertyname="idForValidateLog">
<map>
<entrykey="0"value="32329"/>
</map>
</property>
</bean>
<!-- defines the Interceptors for Inbound logging and outbound logging -->
<beanid="inInterceptor"class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<beanid="outInterceptor"class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<!-- defines the Exceptions Mapper which is used to catch the exceptions thrown during the web service processing -->
<beanid="exceptionMapper"class="com.icil.service.web.exception.mapper.WebServiceExceptionMapper"/>
<!-- defines the Interceptor to decode the incoming message accroding to the specified encoding -->
<beanid="decodeInterceptor"class="com.icil.service.web.interceptor.DecodeInInterceptor"/>
<!-- defines the Interceptor to transform the incoming message e.g. remove the empty parent -->
<beanid="transformInterceptor"class="com.icil.service.web.interceptor.MessageTransformInInterceptor"/>
<!-- defines the web service bean -->
<beanid="serviceImpl"class="com.icil.sofs.web.service.bookingtransfer.impl.SOFS2AFSARestImpl"/>
<!-- the JAX-RS web service server configuration, the service address need to be defined -->
<jaxrs:serverid="transferService"address="/">
<jaxrs:serviceBeans>
<refbean="serviceImpl"/>
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<refbean="xslTranslationInterceptor"/>
<!-- this is the Interceptors configuring, the Interceptore belong to same phase will be executed according to the order defined here -->
<refbean="crossTranslationInterceptor"/>
<refbean="inInterceptor"/>
<refbean="decodeInterceptor"/>
<refbean="transformInterceptor"/>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<refbean="outInterceptor"/>
<refbean="transformoutInterceptor"/>
</jaxrs:outInterceptors>
<jaxrs:providers>
<refbean="exceptionMapper"/>
</jaxrs:providers>
</jaxrs:server>
2.6 Deploy Service
2.6.1 Web Application Deploy
CXF JAX-RS applications packaged as WAR archives can be deployed into standalone Servlet containers such as Tomcat.
/var/lib/tomcat6/webapps/bookingtransfer
/var/lib/tomcat6/webapps/bookingtransfer/WEB-INF#
classes lib web.xml
/var/lib/tomcat6/webapps/bookingtransfer/WEB-INF/lib#
sofs-web-service-bookingtransfer-impl-1.0.0-SNAPSHOT.jar
/var/lib/tomcat6/webapps/bookingtransfer/WEB-INF/classes/resources#
applicationContext.xml
2.6.2 web.xml Configure
CXF uses Spring to provide XML configuration of services. This means that first we'll want to load Spring via a Servlet listener and tell it where our XML configuration file is. Next, you'll need to add CXFServlet to your web.xml:
<!-- specify the spring configuration file location -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/resources/applicationContext.xml</param-value>
<description>contextConfigLocation configuration</description>
</context-param>
<!-- the Spring ContextLoaderLister. This starts Spring and explicitly loads the configuration file -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- defines the URI pattern -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
2.7 Exposing Service URI
Lets assume you have a web application called “bookingtransfer”, CXFServlet's url-pattern is "/services/*" , jaxrs:server's address is “/”.
requests like /bookingtransfer/services will be delivered to one of the resource classes in a given jaxrs:server endpoint. For the former example, a resource class with @Path("/") should be available, then plus the @Path of the method, will direct the final matched method.
e.g. /bookingtransfer/services/post
2.8 Introduction Flow With Example
Introduce BookingTransfer http://192.168.18.224:8888/svn/Enterprise/sofs/trunk/main_body/src_codes/docs/design/SOFS_AFSA_data_exchanges_FS.doc
2.8.1 Implementation of Common Resource
2.8.2 Call DirectUpdateService To Do Backend Handling
3. Client Side Develop
Service client in any platform written with any kind fo language can consume the web service exposed as an URI.
Currently we mainly have two common Service Client. One is for Java system, one is perl system, Developer can choose the proper one according to the language used.
3.1 Java based Service Client
3.2 Perl based Service Client