Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
sorry für den doppelpost, aber ich glaub in diesem forum lesen den beitrag mehr leute...
Hallo,
ich entwickel zurzeit meinen ersten Webservice und hab mir die Grundlagen anhand dieses Tuts: Webservices with Axis2 and the Eclipse Web Tool Platform (WTP) - Tutorial angeignet.
Ich programmiere mit Eclipse für JAVA EE und nutze Tomcat in der Version 6.14 als Server.
Nun habe ich folgende Frage/Problem: Mein Service greift auf eine lokal vorhandene Hardware zu und liest dort einige Sachen aus, wie angeschlossene Rechner, Monitore und Verbindungen. Die Datentypen der jeweiligen Geräte stellt der Treiber zur Verfügung.
Nun habe ich zum Beispiel die Klasse ConsoleImpl welche mir eine Liste aller angeschlossenen Konsolen besorgt und eine Klasse ConsoleService welche die Liste einfach zur Verfügung stellt. Das gleiche auch für Rechner und Verbindungen.
Als Client benötige ich jedoch eine GUI, also einen einzelnen Client welcher auf alle angebotenen Services zugreifen kann.
Wenn ich jedoch einen Client erstelle, erstelle ich ihn ja genau für einen Service, zum beispiel für ConsoleService.
Kann mir jemand sagen was man anders machen muss, bzw was ich falsch mache um das zu erreichen?
Sollte das nicht eher heissen, Wenn ich mir einen Client generieren lasse, wird dieser für genau einen Service generiert.
Also wenn du dir die verschiedenen Clients erstellen läßt, dann werden mehrere Klassen erstellt.
Bei Axis sind das die Stubs etc.
Diese kopierst du in ein neues Projekt und erstellst dir anhand derer einen Client, der auf mehrere Service zugreift.
Oder du referenzierst die Projekte die die generierten Stubs enthalten.
Poste einfach mal die Verzeichnisstrukturen von deinen Clients.
danke für die Antwort. Ja natürlich, ich lasse den Client generieren. Das mit dem kopieren der Stubs hat funktioniert und läuft nun so wie ich das möchte.
Nun hab ich noch eine kleine abschließende Frage: Ich habe eine Liste von Objekten, die vier Felder besitzen.
Mit komplexen Datentypen kommt Axis nicht zurecht. Also war mein erster Gedanke diese Liste in ein Mehrdimensionales Array zu überführen, was jedoch leider auch nicht funktioniert.
Wie bekomme ich die Daten so manipuliert das ich sie an den Client übertragen kann? Eine sehr unschöne Möglichkeit wäre ja die Objekte in ein einfaches Array zu kopieren welches 4 mal so viele Felder hat wie Objekte in der Liste...
Ich muß zugeben, das ich kein großer Freund von Axis2 bin.
Die Eclipseintegration mit den Plugins ist zwar recht schön und Klickibunti, was allerdings den Nachteil hat, das ein paar Grundlagen auf der Strecke bleiben.
Gibt es einen Grund warum du Axis2 machst anstatt Jax-WS.
Der Grobe ablauf ist recht analog.
Webservice bereitstellen
Code:
Webservice erstellen und mit den passenden Annotations versehen.
Webservice veröffentlichen. (siehe Klasse Endpoint)
Client erstellen
Code:
WSDL holen (AdresseZumService?wsdl)
mit dem tool wsimport (im JDK Verzeichnis) und der Wsdl, alle nötigen Artefakte erzeugen lassen.
Komplexe Datentypen werden hierbei mit JaxB verarbeitet.
Mit den erzeugten Artefakten einen Client erstellen.
Es sollte auch möglich sein, Teil 1 mit Axis2 zu erstellen und für den 2. Teil JaxWS zu nutzen.
/**
* FactorSkeleton.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 1.4.1 Built on : Aug 13, 2008 (05:03:35 LKT)
*/
package [url]www.factor;[/url]
/**
* FactorSkeleton java skeleton for the axisService
*/
public class FactorSkeleton{
/**
* Auto generated method signature
*
* @param factor
*/
public [url]www.factor.FactorResponse[/url] factor([url]www.factor.Factor[/url] factor)
{
[url]www.factor.FactorResponse[/url] res = new [url]www.factor.FactorResponse();[/url]
int temp = factor.getFactor().getOp1() * factor.getFactor().getOp2();
res.setFactorResponse(temp);
return res;
}
}
Daraus habe ich einen Webservice erzeugt, welchen ich auch in der Browserleiste aufrufen kann.
und einen Klienten erzeugt Test.java
Java:
public class Test {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
FactorStub stub = new FactorStub();
Factor fac = new Factor();
Operanden op = new Operanden();
op.setOp1(12);
op.setOp2(2);
fac.setFactor(op);
FactorResponse res = stub.factor(fac);
int fres = res.getFactorResponse();
System.out.println(fres);
}
}
aber bekomme folgendes Fehlermeldung
xception in thread "main" org.apache.axis2.AxisFault: First Element must contain the local name, Envelope , but found HTML
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:90)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:353)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at www.factor.FactorStub.factor(FactorStub.java:183)
at www.factor.Test.main(Test.java:25)
Caused by: org.apache.axiom.soap.SOAPProcessingException: First Element must contain the local name, Envelope , but found HTML
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.constructNode(StAXSOAPModelBuilder.java:251)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createOMElement(StAXSOAPModelBuilder.java:209)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createNextOMElement(StAXSOAPModelBuilder.java:191)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:172)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.getSOAPEnvelope(StAXSOAPModelBuilder.java:156)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.<init>(StAXSOAPModelBuilder.java:105)
at org.apache.axis2.builder.BuilderUtil.getSOAPBuilder(BuilderUtil.java:677)
at org.apache.axis2.transport.TransportUtils.createDocumentElement(TransportUtils.java:182)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:112)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:88)
... 6 more
Ich verstehe nicht warum er sich weigert das zu tun.
Mit dem Tool kannst du dir die Nachrichten anschauen die dein Soapclient versendet und die antworten, die du vom Webservice bekommst.
Bei dem Tool stellst du einen freien lokalen Port ein (z.B.9876). Gibst den Server an auf dem der Webservice läuft(127.0.0.1 fals es der gleiche Rechner ist) und den Port auf den dein Webservice hört.
Im generierten Code für den Client, suchst du dann die Adresse des Webservices und ersetzst den Port mit dem den du als lokalen Port (9876) angegeben hast.
Wenn der Client nun läuft siehst du schonmal die Nachrichten, und siehst ob da etwas schief geht.
Du verwendest JaxB nicht direkt. Du würdest JaxWS verwenden. Intern werden die Mappings von XML -> Java und zurück mit JaxB verarbeitet.
Wenn Axis2 auf dem Server ist, heißt das nicht, das der Client auch Axis2 sein muß. WebService heißt es ist mir egal was es für Clients gibt.
import wsclient.Factor;
import wsclient.Factor_Service;
import wsclient.Operanden;
public class WSClient {
public static void main(String[] args) {
Factor_Service factorService = new Factor_Service();
Factor factor = factorService.getFactorSOAP();
Operanden operanden = new Operanden();
operanden.setOp1(1);
operanden.setOp2(2);
factor.factor(operanden);
}
}
In der Wsdl sollte allerdings nicht als soapAddress Example Web Page angegeben sein, sondern der richtige host, bzw. localhost. Zu testzwecken mit dem Port vom tcpmon.
Daraufhin einen Webservice erstellt und diesen im Web Services Explorer getestet und es funkionierte.
Also mit dem Wizard einen Web Service Client generiert und diese Klasse zugefügt:
Java:
package localhost.summe12;
import localhost.summe12.Summe12Stub.CalcSumme;
import localhost.summe12.Summe12Stub.CalcSummeResponse;
import localhost.summe12.Summe12Stub.Summanden;
import org.apache.axis2.AxisFault;
public class Summe12Test {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Summe12Stub stub = new Summe12Stub();
Summanden summanden = new Summanden();
summanden.setSum1(155);
summanden.setSum2(34);
CalcSumme calcum = new CalcSumme();
calcum.setCalcSumme(summanden);
CalcSummeResponse res = stub.CalcSumme(calcum);
System.out.println(res.getCalcSummeResponse());
}
}
und siehe da, es hat funktioniert.
Mal schauen ob ich das auf die etwas komplexeren Datentypen jetzt übernommen bekomme.
Es wäre wirklich schön wenn eclipse zusätzlich noch UML diagramme anfertigen würde damit man sieht wie die klassen die automatisch generiert werden einzusetzen sind.
Aber eine letzte Frage ist noch geblieben: Wenn ich nun den Service so weit wie möglich bei mir am Rechner zu hause entwickel und dann losziehe um ihn bei seinem einsatzort aufzusetzen, wie änder ich dann für alle relevanten Inhalte den Targetnamespace von Domain ist reserviert auf die neue adresse?
daraufhin wieder ein web service angelegt und Cputest12Skeleton wie folgt implementiert:
Java:
/**
* Cputest12Skeleton.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: 1.4.1 Built on : Aug 13, 2008 (05:03:35 LKT)
*/
package localhost.cputest12;
/**
* Cputest12Skeleton java skeleton for the axisService
*/
public class Cputest12Skeleton{
/**
* Auto generated method signature
*
*/
public localhost.cputest12.GetCPUResponse GetCPU
(
)
{
localhost.cputest12.GetCPUResponse res = new localhost.cputest12.GetCPUResponse();
CPU cp = new CPU();
cp.setName("hallo");
cp.setNID("1");
cp.setNNotUsed("2");
cp.setNPower("3");
res.setGetCPUResponse(cp);
return res;
}
}
ich will also erstmal teilweise nur eine einzelne cpu übertragen bevor ich ne ganze liste versuche.
dann wieder anhand der wsdl datei nen client generieren lassen. Dort hab ich angefangen mit
Java:
Cputest12Stub stub = Cputest12Stub();
aber leider steht mir für den stub nicht die methode stub.GetCPU() zur verfügung.
wo liegt denn da mein denkfehler? wo ist der unterschied zum einfachen beispiel mit der summe?