http://www.irit.fr/~philippe.truillet Web Services Tomcat / Axis 1.4 Ph. Truillet Octobre 2013 v. 1.54 1. installing Axis 1.x (not necessary for practical works) Axis is the acronym for Apache extensible Interaction System, formerly SOAP4J developed by IBM. See the Axis installation guide (http://axis.apache.org/axis/java/install.html) for instructions on how to install Axis as a web application on your java server (Apache tomcat for example). Before running the examples in this guide, you'll need to make sure that your CLASSPATH includes: activation.jar axis.jar commons-discovery-0.2.jar commons-logging-1.0.4.jar jaxrpc.jar mail.jar saaj.jar You can found these libraries here: http://www.irit.fr/~philippe.truillet/ens/ens/ostfalia/data/lib.zip First try the url http://<tomcat_ip>:8080/axis/services which will give you the list concerning all services already installed. Figure 1: list of services Try the following url: http://<tomcat_ip>:8080/axis/services/version?method=getversion. Here, you will call getversion method from the service Version.
Page 2 Web services Normally, you will obtain: Figure 2: getversion method 3. webservices There is two ways to publish some webservices with Axis framework: JWS - Java Web Services (instant deployment) And using WSDD Web Service Deployment Descriptions (custom deployment) 3.1 JWS (Java Web Service) Now let's test a JWS web service. Axis' JWS Web Services are java files you save into the Axis webapp anywhere but the WEB-INF tree, giving them the.jws extension. When someone requests the.jws file by giving its URL, it is compiled and executed. To test the JWS service, we make a request against a built-in example, EchoHeaders.jws (look for this in the axis/ directory). Point your browser at http://localhost:8080/axis/echoheaders.jws?method=list. This should return an XML listing of your application headers. Figure 3: SOAP message
Web services Page 3 Exercise: Download file http://www.irit.fr/~philippe.truillet/ens/ens/ostfalia/data/servicebonjou r_jws.zip Rename the file if necessary, by using ftp protocol, put the file ServiceBonjour.jws onto the folder /webapps/axis on the remote computer Open a web browser and type the url: http://<tomcat_ip>:8080/axis/servicebonjour.jws?method=message It works! 3.2 WSDD (Web Service Deployment Descriptions) To use advanced features in terms of deployment, you can use the deployment descriptors. This principle is implemented by Axis to define the methods you want to publish your Web service, the porttype, encoding,... These are not configurable when you deploy a Web service using the principle of JWS mentioned above. You'll have to use WSDD files (Web Service Deployment Descriptors). Create two files specific to each of your Web services, to deploy and the other to remove. By convention, these files are often called deploy.wsdd and undeploy.wsdd. The latter is done by submitting an XML deployment descriptor to the service via the Admin web service, which is usually done with the AdminClient program or the <axis-admin> Ant task. The first step is to add your code to the server. In the WEB-INF directory, look for (or create) a "classes" directory (i.e. axis/web-inf/classes). In this directory, copy the compiled Java classes you wish to install, being careful to preserve the directory structure of the Java packages. If your classes services are already packaged into JAR files, feel free to drop them into the WEB-INF/lib directory instead. Also add any third party libraries you depend on into the same directory. After adding new classes or libraries to the Axis webapp, you must restart the webapp. This can be done by restarting your application server, or by using a server-specific mechanism to restart a specific webapp. Concerning wsdd files, you must set the "service" tag by specifying attribute: Web Service name so that it is identified by your application server mode: RPC (Remote Procedure Call) You must define at least two "parameter" tags. One of these tags must define the name of the associated Web service you want to deploy class. Indeed, the particularity of the deployment descriptor is able to specify a service name different from the name of the class describing its behavior. The second tag "parameter" is used to define accessible from the Web Service methods. This is an example of deploy.wsdd to use with the example (ServiceBonjour) <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="servicebonjour" style="rpc"> <parameter name="classname" value="servicebonjour"/> <parameter name="allowedmethods" value="*"/> </service> </deployment> Figure 4: deploy.wsdd file And this is an example for undeploy.wsdd to use to uninstall the web service (ServiceBonjour) <undeployment xmlns="http://xml.apache.org/axis/wsdd/"> <service name="servicebonjour"/> </undeployment> Figure 5: undeploy.wsdd file Exercise: Step 1: rename ServiceBonjour.jws to ServiceBonjour.java. Compile the class ServiceBonjour Step 2: define a WSDD file (cf. figure 3) or download it from this location: http://www.irit.fr/~philippe.truillet/ens/ens/ostfalia/data/deploy.zip
Page 4 Web services Step 3: install the code. You have to put file on the server on the /webapps/axis/web-inf/classes directory Step 4: déployment. On the server, use the following command line: java org.apache.axis.client.adminclient deploy.wsdd You can use the file deploiement.bat Step 5: execute your service by using the following location: http://<tomcat_ip>:8080/axis/services/servicebonjour?method=message Step 6 (optionnal): uninstall the service java org.apache.axis.client.adminclient undeploy.wsdd 4. advanced deployment 4.1 clients for services web Figure 6: the service is installed It is of course possible to use the web service by using client directly written in Java, more suitable for integration with other applications! The structure consists of: 1. 1. Creating a service access 2. 2. Creating a call to service 3. url service access retrieval 4. method to applied 5. Implementation of possible values for parameters 6. service invocation 7. take results Exercise: Download ClientServiceBonjour.zip from: http://www.irit.fr/~philippe.truillet/ens/ens/ostfalia/data/clientservicebonjou r.zip Open file ClientServiceBonjour.java, compile and launch it (by using file compile_n_go.bat or ant demo)
Web services Page 5 4.2 restricting client access Performing a deployment that allows access to all methods of service we give too much visibility of the service. Thus, it may be that you use internal methods that the service is useless and even dangerous expose. To prevent access to this method, there are two solutions: Either make private methods (private keyword) which will make this invisible method for customers. However, this is not always possible to the extent that we sometimes want to make available this method to other objects (servers between other objects) without making it visible to customers. Or, to overcome this difficulty, we can keep the public method (public keyword) but prevent access to clients. In this case, you must explicitly specify the content in the deployment descriptor, specifying only the methods available to clients. Ex: <parameter name="allowedmethods" value="method1 method2 method3"/> 4.3 data persistence Whenever a service method is invoked (actually, every time you use the service), the Axis server, before invoking the requested method creates a new instance of class. Therefore, each method invocation, we will always have a new body that will be obtained with the default constructor (corresponds to the deployment line <parameter name="scope" value="request"/>) To avoid this problem, we must clarify that access to the service must be associated with either the user session (using the same browser, for example) or for any requests from any client. To do this, you must include in the deployment descriptor of the service the following line: <parameter name="scope" value="session"/> or respectively <parameter name="scope" value="application"/> 4.4. exercises 1. Create a web service to manage a bank account ServiceCompte. Define the java class Compte with the following methods: public class Compte { float balance; // Constructor public Compte() { Solde = 0.0; public void deposit (float value) { public boolean withdraw (float value) { // return true if balance is positive, false elsewhere public float balance() { Then test the service via a web browser. http://<tomcat_ip>:8080/axis/services/servicecompte?method=balance http://<tomcat_ip>:8080/axis/services/servicecompte?method=deposit&value=150 http://<tomcat_ip>:8080/axis/services/servicecompte?method=withdraw& value =100 http://<tomcat_ip>:8080/axis/services/servicecompte?method=deposit& value =250 http://<tomcat_ip>:8080/axis/services/servicecompte?method=balance 2. Create a java client that uses the ServiceCompte service. We want to make deposits, withdrawals and view the actual balance. Perform the same operations as above. 3. Create an online ServiceAnnuaire yellow pages service and client using this service.
Page 6 Web services 5. go further: complex objects 5.1 the recurring problem of serialization The interoperability between SOAP implementation is a big challenge. By default, Axis cannot send arbitrary Java objects and wait until they are necessarily understood by the client. Unlike RMI, where both sides, you can send and receive serialized java objects, Axis can send "by default" primitive types, or objects registered by the Axis serializer but composed types primitive data. Here are the standard objects mapped by WSDL: xsd:base64binary xsd:boolean xsd:byte xsd:datetime xsd:decimal xsd:double xsd:float xsd:hexbinary xsd:int xsd:integer xsd:long xsd:qname xsd:short xsd:string byte[] boolean byte java.util.calendar java.math.bigdecimal double float byte[] int java.math.biginteger long javax.xml.namespace.qname short java.lang.string If the returned object is null, then the primitive data types are replaced by their encapsulation class as Byte, Double, Boolean, etc. In the case where the objects are composed of primitive data types, it can be necessary to tell Axis which Java classes "to map" with XML-Schema types. A WSDD deployment configuration file looks like this: <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="serviceannuaire" provider="java:rpc"> <parameter name="classname" value="serviceannuaire"/> <parameter name="scope" value="application"/> <parameter name="allowedmethods" value="*"/> <beanmapping </service> </deployment> qname="myns:fiche" xmlns:myns="urn:serviceannuaire" languagespecifictype="java:fr.irit.diamant.ws.annuaire.fiche"/> The <beanmapping> tag maps a Java class to the XML attribute QName. Two attributes are important: qname and languagespecifictype. In the example above, we map "fr.irit.diamant.ws.annuaire.fiche" to the XML QName ServiceAnnuaire: Fiche A client who uses the class has to be also modified! You should indicate how to serialize and deserialize complex objects. The client incorporates then import javax.xml.namespace * in the code: QName qn = new QName( "urn:serviceannuaire", "Fiche" ); call.registertypemapping(fiche.class, qn, new org.apache.axis.encoding.ser.beanserializerfactory(fiche.class, qn), new org.apache.axis.encoding.ser.beandeserializerfactory(fiche.class, qn)); We can therefore use the complex object argument or callback functions. Another method exists, especially in case of adaptation over previously existing serialization / deserialization classes. For more details, cf. org.apache.axis.encoding.ser package. For deployment, ArrayMapping or typemapping attributes are then used.
Web services Page 7 5.2 exercise 1. Create ServiceAnnuaire the online yellow page service Which uses an directory service composed of Fiches That offers the following methods: a. add: adds a record to the directory b. searchbyname: which allows you to search a listing by name and returns a vector consisting of records that match the criteria c. getnumfiches: which returns the number of entries in the directory d. getfiches: that returns a vector composed of all the pages directory 2. And a client using this service.