Dienstag, 22. Mai 2012


Artikel

Januar 2007 | Artikel

Axis2 versus XFire – Das Duell Fortsetzung, Teil 4

Teil 1   Teil 2   Teil 3   Teil 4   

Auch wenn sich die services.xml in der Syntax unterscheiden, so kann man festhalten, dass beide Projekte an dieser Stelle nahezu die gleichen Konfigurationsmöglichkeiten bieten: Definition von Services, Festlegen von Methoden, Message Styles, Message Receivern/Invokern, Handlern usw. Für den XFire Web Service benö­tigt man unter Umständen noch eine web.xml, die eingehende Anfragen an das XFire­Servlet delegiert (Listing 6). Um die Archive zum Deployment des Web Services zu erzeugen, soll ein Ant-Skript zum Einsatz kommen. Listing 7 zeigt, wie so ein Skript aussehen könnte. In Abbildung 3 ist noch mal das komplette Eclipse-Projekt dargestellt.

  1. Listing 6: web.xml für XFire
  2. ------------------------------------------------------------------
  3. <!DOCTYPE web-app
  4. PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  5. "http://java.sun.com/dtd/web-app_2_3.dtd">
  6. <web-app>
  7. <servlet>
  8. <servlet-name>XFireServlet</servlet-name>
  9. <display-name>XFire Servlet</display-name>
  10. <servlet-class>
  11. org.codehaus.xfire.transport.http.XFireConfigurableServlet
  12. </servlet-class>
  13. </servlet>
  14. <servlet-mapping>
  15. <servlet-name>XFireServlet</servlet-name>
  16. <url-pattern>/servlet/XFireServlet/*</url-pattern>
  17. </servlet-mapping>
  18. <servlet-mapping>
  19. <servlet-name>XFireServlet</servlet-name>
  20. <url-pattern>/services/*</url-pattern>
  21. </servlet-mapping>
  22. </web-app>
  1. Listing 7: Ant-Skript zum Bauen der Axis2- und XFire Web Services
  2. -----------------------------------------------------------------------------
  3. <?xml version="1.0"?>
  4. <project name="BookService" basedir="." default="ErzeugeAAR">
  5. <property name="src.dir" value="src"/>
  6. <property name="web.dir" value="war"/>
  7. <property name="bin.dir" value="bin"/>
  8. <property name="Axis2Config.dir" value="Axis2Config"/>
  9. <property name="xfirelib" value="C:\xfire-1.2.1"/>
  10. <property name="XFireConfig.dir" value="XFireConfig"/>
  11. <property name="classes.dir" value="${web.dir}/WEB-INF/classes"/>
  12. <property name="lib.dir" value="${web.dir}/WEB-INF/lib"/>
  13. <property name="deploy.file" value="BookService"/>
  14. <property name="deploy.path" value="C:\"/>
  15. <target name="XFireStructure" depends=""
  16. description="[XFIRE] Struktur für WAR-File erzeugen">
  17. <mkdir dir="${web.dir}" />
  18. <mkdir dir="${web.dir}/WEB-INF" />
  19. <mkdir dir="${classes.dir}" />
  20. <mkdir dir="${classes.dir}/META-INF/xfire" />
  21. <copy todir="${classes.dir}" preservelastmodified="true">
  22. <fileset dir="${bin.dir}"
  23. includes="**/*.*"
  24. excludes="*.xml"/>
  25. </copy>
  26. <copy todir="${classes.dir}/META-INF/xfire" preservelastmodified="true">
  27. <fileset dir="${XFireConfig.dir}"
  28. includes="services.xml"/>
  29. </copy>
  30. <copy todir="${lib.dir}">
  31. <fileset dir="${xfirelib}" includes="xfire-all-1.2.1.jar" /> <fileset dir="${xfirelib}\lib" includes="*.jar" />
  32. </copy>
  33. </target>
  34. <target name="ErzeugeWAR" depends="XFireStructure"
  35. description="[XFIRE] WAR-File erzeugen">
  36. <war destfile="${deploy.path}/${deploy.file}.war"
  37. webxml="${XFireConfig.dir}/web.xml">
  38. <fileset dir="${web.dir}">
  39. <include name="**/*.*"/>
  40. </fileset>
  41. </war>
  42. <copy todir="${deploy.path}" preservelastmodified="true">
  43. <fileset dir=".">
  44. <include name="*.war"/>
  45. </fileset>
  46. </copy>
  47. <delete dir="${web.dir}" />
  48. </target>
  49. <target name="Axis2Structure" depends=""
  50. description="[AXIS2] Struktur für AAR-File erzeugen">
  51. <mkdir dir="${web.dir}" />
  52. <mkdir dir="${web.dir}/META-INF" />
  53. <copy todir="${web.dir}" preservelastmodified="true">
  54. <fileset dir="${bin.dir}"
  55. includes="**/*.*"
  56. excludes="*.xml"/>
  57. </copy>
  58. <copy todir="${web.dir}/META-INF" preservelastmodified="true">
  59. <fileset dir="${Axis2Config.dir}"
  60. includes="services.xml"/>
  61. </copy>
  62. </target>
  63. <target name="ErzeugeAAR" depends="Axis2Structure"
  64. description="[AXIS2] AAR-File erzeugen">
  65. <jar destfile="${deploy.path}/${deploy.file}.aar">
  66. <fileset dir="${web.dir}">
  67. <include name="**/*.*"/>
  68. </fileset>
  69. </jar>
  70. <copy todir="${deploy.path}" preservelastmodified="true">
  71. <fileset dir=".">
  72. <include name="*.aar"/>
  73. </fileset>
  74. </copy>
  75. <delete dir="${web.dir}" />
  76. </target>
  77. </project>

Nach dem Ausführen des Tasks <ErzeugeAAR> sollte auf C:\ eine Datei mit dem Namen BookService.aar existieren, diese kann nun nach Axis2 hochgeladen werden. Unter folgendem URL ist die WSDL­ der Axis2-Version des Web Services jetzt verfügbar: http://localhost:8080/axis2/services/Book-Service?wsdl. Wird bei Axis2 ?wsdl durch ?xsd ersetzt, dann erhält man zusätzlich noch ein XML-Schema für den Service. Das Ausführen des Tasks <ErzeugeWAR> führt zur Datei BookService.war, die dann in einen Servlet-Container eingespielt werden kann. Die WSDL des XFire Web Services ist dann hier verfügbar: http://localhost:8080/BookService/services/BookService?wsdl.

Zum Abschluss fehlt noch der Client. Aus Platzgründen kann leider nur ein Client besprochen werden. Dieser soll mit Axis2 implementiert werden, da man hier aufgrund von AXIOM etwas aufwendiger (im Gegensatz zu einem XFire-Client) entwickeln muss. Der Client (Listing 8) ruft beide Methoden des Service auf und gibt die entsprechenden Bücher samt Autoren aus.

  1. Listing 8: Ein Web-Service-Client, wie er mit Axis2 programmierbar ist
  2. -------------------------------------------------------------------------------
  3. package de.javamagazin;
  4. import java.util.ArrayList;
  5. import javax.xml.namespace.QName;
  6. import org.apache.axiom.om.OMElement;
  7. import org.apache.axis2.AxisFault;
  8. import org.apache.axis2.addressing.EndpointReference;
  9. import org.apache.axis2.client.Options;
  10. import org.apache.axis2.databinding.utils.BeanUtil;
  11. import org.apache.axis2.rpc.client.RPCServiceClient;
  12. public class Axis2Client {
  13. private static EndpointReference endpoint = new EndpointReference(
  14. "http://localhost:8080/axis2/services/BookService");
  15. private static QName findBookOperation = new QName(
  16. "http://javamagazin.de/xsd", "findBook");
  17. private static QName getBooksOperation = new QName(
  18. "http://javamagazin.de/xsd", "getBooks");
  19. public static void main(String[] args) {
  20. try {
  21. Options options = new Options();
  22. options.setTo(endpoint);
  23. RPCServiceClient sender = new RPCServiceClient();
  24. sender.setOptions(options);
  25. ArrayList arguments = new ArrayList();
  26. arguments.add("978-3-935042-81-9");
  27. OMElement response = sender.invokeBlocking(findBookOperation,
  28. arguments.toArray());
  29. Book book = (Book) BeanUtil.deserialize(Book.class, response
  30. .getFirstElement());
  31. printBook(book);
  32. ArrayList resobj = new ArrayList();
  33. resobj.add(Book.class);
  34. resobj.add(Book.class);
  35. Object[] returned = sender.invokeBlocking(getBooksOperation,
  36. new ArrayList().toArray(), resobj.toArray());
  37. for (Object o : returned) {
  38. book = (Book) o;
  39. printBook(book);
  40. }
  41. } catch (AxisFault axisFault) {
  42. axisFault.printStackTrace();
  43. }
  44. }
  45. private static void printBook(Book book) {
  46. System.out.println("Title: " + book.getTitle());
  47. for (int i = 0; i < book.getAuthors().length; i++) {
  48. System.out.println("Autor " + i + ": "
  49. + book.getAuthors()[i].getName() + ", "
  50. + book.getAuthors()[i].getFirstName());
  51. }
  52. System.out.println("\n");
  53. }
  54. }

Interessant ist hier das Zusammenspiel mit AXIOM: Nachdem über einen RPCServiceClient die Methode aufgerufen wurde, bekommt man ein OM-Element zurück. Hierbei handelt es sich um das bereits angesprochene Wrapper-Objekt von AXIOM. Über eine Hilfsmethode der Klasse BeanUtil, ebenfalls Bestandteil von Axis2, lässt sich der Wrapper jedoch wieder sehr leicht in das erwartete Book-Objekt serialisieren.

Marc Teufel arbeitet als Entwickler bei der hama GmbH & Co KG. Er ist Autor zahlreicher Fachartikel in den Bereichen .NET und Java, hat bereits ein Buch über Apache Axis veröffentlicht  und schreibt derzeit mit zwei anderen Autoren an einem Buch zu Apache Axis2. Kontakt: marc.teufel[at]hama.de.
  1. XFire
  2. Apache Axis2
  3. Apache Axis 1.x
  4. Tabellarischer Vergleich der einzelnen Features
  5. Übersicht WS*-Spezifikationen

Teil 1   Teil 2   Teil 3   Teil 4   

Kommentare