# Web Services mit axis



## chipmount (18. Dezember 2004)

hallo Leute,
ich möchte folgendes tun:
nach Vorgabe des Bestellernamens werden alle enstprechende DB-Tabellen gefunden und zur Verfügung gestellt

es ist ein WSDL Dokument, Custom Deployment und ein client Programm zu erstellen

irgendwie hab ich keine AHNUNG wie das aussehen soll und aus der axis beschreibung bin ich auch nicht schlauer geworden 
ich verstehe nicht wohin die einzelnen datein/classen kommen und wie die "compiliert " werden

hat jemand eine Idee oder ein gutes tutorial

danke


----------



## cham (19. Dezember 2004)

So richtig weiß ich noch nicht, was Dein Problem ist. Compiliert wird von Seiten Axis gar nichts, nur generiert, wenn Du von Deinem WSDL  java generieren läßt. Geh mal den Userguide durch und versuche die Beispiele nachzuvollziehen. Dann wird es sicher klarer.


----------



## masterjcl (19. Dezember 2004)

ftp.borland.com/pub/jbuilder/techpubs/german/wecvs.pdf


----------



## chipmount (19. Dezember 2004)

ist das so richtig? 

für die aufgabe hab ich mir folgendes überlegt 

unter C:/Tomcat5/webapps/axis 

lege ich meine datei DB.jws (die die JDBC anbindung/abfrage beinhaltet mit return werten) 

desweiteren hab ich unter C:/Tomcat5/webapps/axis/WEB-INF/classes/TEST <-angelegt 
wo sich folgendes befindet: 
cp.bat (CLASSPATH) 
wsdl.bat (call cp.bat java org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/...jws?WSDL) 
client.java 

nur für was brauche ich jetzt Custom Deployment ?


----------



## cham (19. Dezember 2004)

Also was Du mit den Webservices tust oder wie die funktionieren ist für die Webservidefunktion unerheblich.

Du musst ein WSDD File für das Deployment erstellen in welchem Deine Methoden und Klassenentsprechungen drinstehen. Das musst du dann entsprechend im Axis deployen.

Schau mal da: http://rzm-hamy-wsx.rz.uni-karlsruhe.de/Training/SOAP-1/html-generated/axis-wsdl-2.html Dort gibt es einige Beispiele. 

Aber es steht auch komplett in der Axis Doku: http://ws.apache.org/axis/java/user-guide.html#PublishingServices

Du kannst Deine deployten Webservices unter http://yourserver:yourPort/axis/servlet/AxisServlet anschauen.


----------



## chipmount (20. Dezember 2004)

aber ich dachte axis erstellt selbst eine wsdd   
 in welchen verzeichniss muss ich denn die wsdd datei abspeichern
und mich welchen befehl deployed man?

danke


----------



## cham (20. Dezember 2004)

das custom bei custom deployment besagt, dass du es selbst erstellen musst. erstellt mird es nur, wenn Du Dir die Stubs aus nem Interface generieren läßt.

Schau Dir bitte den Link an. Das Verzeichnis ist egal. Es muss nur angegeben werden. (Aufruf: 
	
	
	



```
java org.apache.axis.client.AdminClient deploy.wsdd
```
 )


----------



## chipmount (20. Dezember 2004)

so jetz hab ich mal geschaft eine ..wsdl, deploy.wsdd, undeploy.wsdd und einige ...Soap..java dateine zu erstellen dann hab ich mit 

```
java org.apache.axis.client.AdminClient  -p 8081 -l local://	 ..../deploy.wsdd
```
registriert
nur ich sehe sie unter http://yourserver:yourPort/axis/servlet/AxisServlet  nicht sehen


----------



## Thomas Darimont (21. Dezember 2004)

Hallo!

Ich hab mich gestern auch mal mit Axis auseinander gesetzt und ein kleines 
Beispiel zum laufen gebracht.

Umgebung: WinXP Pro., Java 5.0, Tomcat 5.0.28, Axis 1.2RC2

Zuerst habe ich eine Klasse erstellt welche die von mir gewünschte Methode bereitstellt.


```
/*
 * Created on 21.12.2004@10:11:30
 *
 * TODO Explain me...
 */
package de.tutorials.ws;

import java.util.Date;

/**
 * @author Darimont
 *
 * TODO Comment me
 */
public class MyWebservice {
    public String getServerTime(String param) {
        return new Date() + "_" + param;
    }
}
```

Diese Klasse (das .class File) packen wir nun in ein jar -> example.jar und legen es ins 
axis/WEB-INF/lib Verzeichnis des Webapps Ordners im Tomcat...
Falls dort noch kein axis Verzeichnis sein sollte, müsst ihr noch das axis Verzeichnis aus dem webapps
Ordner der "eurer" Axis Distribution in das Tomcat Webapps Verzeichnis  kopieren.
Nun könnt ihr den Tomcat starten und unter der Adresse:
http://localhost:8080/axis 
findet ihr nun die Einstiegsseite von Axis.
Mit einem Klick auf Validate könnt ihr eure Installation überprüfen lassen.
...
Dabei kann es vorkommen, dass axis bestimmte Classen nicht finden kann ... sollte das der Fall sein
müsst ihr Axis noch die beiden Jars (activation.jar und mail.jar) verfügbar machen. (Diese beiden jar's liegen
z.Bsp. der aktuellen Version des Springframeworks http://www.springframework.org (incl. all dependencies...).
Diese jars könnt ihr dann beispielsweise ins common/lib Verzeichnis des Tomcats kopieren.
Bei erneuter Überprüfung der Installation sollte nun in der "Validate-Ausgabe" folgendes zu lesen sein:


> The core axis libraries are present. 1 optional axis library is missing



Nun fehlt uns hier zwar immer noch eine Bibliothek aber das ignorieren wir der Einfachheit einfach mal.
Nun schreiben wir uns zwei Webservice Deployment Descriptoren.
Einen zum Deployen (installieren)

deploy.wsdd

```
<?xml version="1.0"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 
 <service name="ServerTimeService" provider="java:RPC">
  <parameter name="className" value="de.tutorials.ws.MyWebservice"/>
  <parameter name="allowedMethods" value="*"/>
     <operation name="getServerTime">
      <parameter name="MeinNameIst" mode="IN"/>
     </operation>
 </service>
</deployment>
```


und einen zum Undeployen(deinstallieren)
undeploy.wsdd

```
<?xml version="1.0" encoding="UTF-8" ?>
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
  <service name="ServerTimeService"/>
</undeployment>
```
Beide Dateien legen wir z.bsp im Verzeichnis c:\wsdd ab

Nun können wir mittels des AdminClients von Axis die Webservices beliebig deployen und undeployen

Zur einfacheren Verwendung könnte man dazu folgende Batchdateien verwenden:
setEnv.cmd

```
@echo off
set AXISROOT=C:\jakarta-tomcat-5.0.28\webapps\axis\WEB-INF\lib
set TOMCATROOT=C:\jakarta-tomcat-5.0.28

set CP=.
set CP=%CP%;%AXISROOT%\axis.jar
set CP=%CP%;%AXISROOT%\axis-ant.jar
set CP=%CP%;%AXISROOT%\commons-discovery.jar
set CP=%CP%;%AXISROOT%\commons-logging.jar
set CP=%CP%;%AXISROOT%\jaxrpc.jar
set CP=%CP%;%AXISROOT%\log4j-1.2.4.jar
set CP=%CP%;%AXISROOT%\saaj.jar
set CP=%CP%;%AXISROOT%\wsdl4j.jar
set CP=%CP%;%TOMCATROOT%\common\lib\servlet.jar
set CP=%CP%;%TOMCATROOT%\common\lib\mail.jar
set CP=%CP%;%TOMCATROOT%\common\lib\activation.jar
set CLASSPATH=%CP%
```

hier die AdminClient.cmd (setEnv.cmd muss im gleichen Verzeichnis liegen)

```
call .\setEnv.cmd
java org.apache.axis.client.AdminClient %1
```

Zum deployen rufen wir nun:


> AdminClient.cmd c:\wsdd\deploy.wsdd


auf.

Zum undeployen rufen wir:


> AdminClient.cmd c:\wsdd\undeploy.wsdd


auf.

Zu beachten ist hier, dass der Axis AdminClient standardmäßig annimmt, dass der Tomcat auf Port 8080 läuft. Ist das nicht der Fall muss man den richtigen Port mitgeben wie das geht entnehme man bitte den vorangegangenen Beiträgen.

Wenn wir danach die Seite:
http://localhost:8080/axis/servlet/AxisServlet
aufrufen sollte nun unser neuer ServerTimeService erscheinen.
Mit einem Klick auf "wsdl" generiert uns axis eine WSDL Beschriebung unseres Webservices.
(oder -> http://localhost:8080/axis/services/ServerTimeService?wsdl )
Die dann wie folgt aussehen könnte:

```
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://localhost:8080/axis/services/ServerTimeService" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://10.50.40.222:8080/axis/services/ServerTimeService" xmlns:intf="http://10.50.40.222:8080/axis/services/ServerTimeService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.2RC2 Built on Nov 16, 2004 (12:19:44 EST)-->
   <wsdl:message name="getServerTimeRequest">
      <wsdl:part name="MeinNameIst" type="soapenc:string"/>
   </wsdl:message>
   <wsdl:message name="getServerTimeResponse">
      <wsdl:part name="getServerTimeReturn" type="soapenc:string"/>
   </wsdl:message>
   <wsdl:portType name="MyWebservice">
      <wsdl:operation name="getServerTime" parameterOrder="MeinNameIst">
         <wsdl:input message="impl:getServerTimeRequest" name="getServerTimeRequest"/>
         <wsdl:output message="impl:getServerTimeResponse" name="getServerTimeResponse"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="ServerTimeServiceSoapBinding" type="impl:MyWebservice">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="getServerTime">
         <wsdlsoap:operation soapAction=""/>
         <wsdl:input name="getServerTimeRequest">
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.50.40.222:8080/axis/services/ServerTimeService" use="encoded"/>
         </wsdl:input>
         <wsdl:output name="getServerTimeResponse">
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://10.50.40.222:8080/axis/services/ServerTimeService" use="encoded"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="MyWebserviceService">
      <wsdl:port binding="impl:ServerTimeServiceSoapBinding" name="ServerTimeService">
         <wsdlsoap:address location="http://localhost:8080/axis/services/ServerTimeService"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>
```


Wollen wir unseren Webservice mal mit dem Browser ausprobieren müssen wir nur die folgende URL aufrufen:
http://localhost:8080/axis/services/ServerTimeService?method=getServerTime&MeinNameIst=Thomas

Wie oben zu sehen ist
-> ServerTimeService der Name unseres veröffentlichten Webservice
-> getServerTime der Name unserer Veröffentlichten Operation
-> Thomas der Wert welchen über den Parameter MeinNameIst an die Operation getServerTime übertragen wird.

Die Ausgabe könnte nun wie folgt aussehen:

```
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <getServerTimeResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <getServerTimeReturn xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Tue Dec 21 10:39:22 CET 2004_Thomas</getServerTimeReturn> 
  </getServerTimeResponse>
 </soapenv:Body>
</soapenv:Envelope>
```

//Edit.

Ein einfacher Java Client sähe dann in etwa so aus:
(Achtung, alle Jar's (bis auf axis-ant.jar) aus dem Verzeichnis axis/lib der Axis Distribution + (activation.jar,mail.jar) [aus diversen Quellen]) müssen im Classpath liegen.

```
/*
 * Created on 20.12.2004@12:54:27
 *
 * TODO Explain me...
 */
package com.somecompany.migration.core;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

/**
 * @author Darimont
 *
 * TODO Comment me
 */
public class Main {

    public static void main(String[] args) {
        try {
            String endpoint = "http://localhost:8080/axis/services/ServerTimeService";
            Service service = new Service();
            Call call = (Call) service.createCall();

            call.setTargetEndpointAddress(new URL(endpoint));
            call.setOperationName(new QName("http://localhost:8080/",
                    "getServerTime"));
            String ret = (String) call.invoke(new Object[] { "Tom" });
            System.out.println(ret);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }
}
```

Die Log4j Warnmeldungen ignorieren wir einfach mal...

Weiterhin viel Spaß mit Axis ;-)

HTH,
Gruß Tom

Ps.: Zwei nette Alternativen zu Axis stellen übrigens Hessian und Burlap dar:

http://www.caucho.com/hessian/
http://www.caucho.com/burlap/


----------



## chipmount (21. Dezember 2004)

nach einigen test hab ich das auch hinbekommen

nur leider hab ich einen fehler irgendwo gemacht aber ich weiß nicht wo

also ich hab jetz folgendes gemacht:

eine Custom Deployment Datei(Die die Eingabe(name) übernimtt und ein Ergebniss an den Client liefert)
die sieht so aus:
iN.java  /(iN.class)

```
public interface iN
{
 public String getMessage();
 public  void insert(String name);
 
}
```
 
daraus erstelle ich meine iN.wsdl , deploy.wsdd, undeploy.wsdd sowie dazugehörigen Classen(Stub...java, ServiceLocator..java, Skeleton...java, etc)

dann erweitere ich die generirte classe ..SoapBindingIml.java


```
/**
 * SNSoapBindingImpl.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis WSDL2Java emitter.
 */
package namespace;
import java.sql.*;
 
public class SNSoapBindingImpl implements namespace.IN{

 private String inout;
 private String answer;
 
	public java.lang.String getMessage() throws java.rmi.RemoteException {
		return  answer;
	}
	public void insert(java.lang.String in0) throws java.rmi.RemoteException 
	{
		
	 Connection c = null; 
		PreparedStatement p = null; 
	
	
  String sql="SELECT bestnr,bestelldatum,bestsum FROM Bestellung WHERE name =?";
	
  String answer="<table style= \"width: 450px\">"+
	 "<tr><td>bestnr</td><td>bestelldatumr</td><td>bestsum</td></tr>";
	try 
	{ 
	  Class.forName ("oracle.jdbc.driver.OracleDriver"); 
	  c = DriverManager.getConnection("jdbc:oracle:thin:@:1521:", "scott", "tiger"); 
	  PreparedStatement ps = c.prepareStatement(sql);
	   
	   Statement s = c.createStatement();
	   ps.setString(1, in0);
  ResultSet rs = ps.executeQuery();
	   
	  while (rs.next())
	  {
	   answer = answer +"<tr>"+
	   "<td>" + rs.getString("bestnr") +"</td>"+
	   "<td>" + rs.getString("bestelldatum") +"</td>"+
	   "<td>" + rs.getString("bestsum") +"</td>"+
	   "</tr>";
			
	   }//end while
	   c.close();
	   answer = answer + "</table>";
	} 
	catch (Exception e) 
	{ 
	  e.printStackTrace();
	  answer = e.toString(); 
	} 
	 inout=answer;
	
  }
   
}
```
 
mein client programm sieht so aus:


```
import namespace.*;
import java.net.*;
public class client
{
 public static void main (String []args) throws java.lang.Exception
 {
  INServiceLocator loc = new INServiceLocator();
   namespace.IN service = loc.getsN(new URL("http://localhost:8081/axis/services/sN"));
  service.insert());
  System.out.println(service.getMessage());
 }
}
```
 
nach der anmeldung des services wenn ich  das client programm ausführe (mit parameter)
krige ich als ausgabe "null" raus

hab ich was vergessen oder was falsch gemacht?
danke


----------

