SOAP-Webservices in Java Beispiel
SOAP-Webservices in Java können auf viele Arten entwickelt werden. Im letzten Tutorial haben wir über JAX-WS SOAP Web Services gelernt, heute werden wir erfahren, wie wir einen SOAP-Webservice und dessen Client-Programm mit Eclipse erstellen können. Hier verwenden wir nicht JAX-WS, sondern Apache Axis, das in Eclipse integriert ist und eine schnelle und einfache Möglichkeit bietet, eine Anwendung in einen Java Web Service zu verwandeln und Client-Stubs mit Test-JSP-Seite zu erstellen.
SOAP-Webservices in Java
Ich verwende Eclipse Mars Release (4.5.0) für dieses Tutorial, aber ich denke, diese Schritte funktionieren auch mit älteren Versionen von Eclipse. Stellen Sie auch sicher, dass Sie Apache Tomcat oder einen anderen Servlet-Container als Server in Eclipse hinzugefügt haben. Beginnen wir jetzt mit unserer Eclipse-Web-Service-Implementierung.
SOAP-Webservice-Beispiel in Eclipse
Beginnen wir mit unserem SOAP-Webservice-Beispiel in Eclipse. Zunächst erstellen wir ein einfaches Dynamic Web Project in Eclipse, das die Geschäftslogik für unsere Anwendung enthält.
Klicken Sie auf den Weiter-Button oben, und Sie gelangen auf die nächste Seite, um den Namen Ihres Webprojekts und die Ziel-Laufzeitumgebung anzugeben. Beachten Sie, dass ich Apache Tomcat 8 verwende, aber Sie können auch jeden anderen Standard-Servlet-Container verwenden.
Klicken Sie auf Weiter und Sie werden gebeten, „Context Root“ und den Ort des Inhaltsverzeichnisses anzugeben. Sie können diese als Standard belassen.
Klicken Sie auf Fertigstellen und Eclipse erstellt das Projektgerüst für Sie. Beginnen wir mit unserer Geschäftslogik. Für unser Beispiel möchten wir einen Webservice veröffentlichen, der zum Hinzufügen/Löschen/Abfragen eines Objekts verwendet werden kann. Der erste Schritt besteht darin, eine Modell-Bean zu erstellen.
package com.journaldev.jaxws.beans;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = -5577579081118070434L;
private String name;
private int age;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString(){
return id+"::"+name+"::"+age;
}
}
Beachten Sie, dass oben eine einfache Java-Bean steht, wir implementieren das Serializable-Interface, weil wir es über das Netzwerk transportieren werden. Wir haben auch eine toString-Methode implementiert, die verwendet wird, wenn wir dieses Objekt auf der Clientseite ausgeben. Der nächste Schritt ist das Erstellen von Serviceklassen, wir werden eine Schnittstelle als PersonService haben und deren einfache Implementierungsklasse PersonServiceImpl.
package com.journaldev.jaxws.service;
import com.journaldev.jaxws.beans.Person;
public interface PersonService {
public boolean addPerson(Person p);
public boolean deletePerson(int id);
public Person getPerson(int id);
public Person[] getAllPersons();
}
Unten befindet sich die Implementierungsklasse des Services, wir verwenden eine Map, um Person-Objekte als Datenquelle zu speichern. In der realen Programmierung würden wir diese in Datenbanktabellen speichern.
package com.journaldev.jaxws.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.journaldev.jaxws.beans.Person;
public class PersonServiceImpl implements PersonService {
private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
@Override
public boolean addPerson(Person p) {
if(persons.get(p.getId()) != null) return false;
persons.put(p.getId(), p);
return true;
}
@Override
public boolean deletePerson(int id) {
if(persons.get(id) == null) return false;
persons.remove(id);
return true;
}
@Override
public Person getPerson(int id) {
return persons.get(id);
}
@Override
public Person[] getAllPersons() {
Set ids = persons.keySet();
Person[] p = new Person[ids.size()];
int i=0;
for(Integer id : ids){
p[i] = persons.get(id);
i++;
}
return p;
}
}
Das ist alles für unsere Geschäftslogik, da wir diese in einem Webdienst verwenden werden, gibt es keinen Grund, hier Webseiten zu erstellen. Beachten Sie, dass wir in dem oben genannten Code keine Referenz auf irgendwelche Webservice-Klassen haben.
SOAP-Webservices in Java mit Eclipse
Sobald unsere Geschäftslogik fertig ist, besteht der nächste Schritt darin, Eclipse zu verwenden, um daraus eine Webservice-Anwendung zu erstellen. Erstellen Sie ein neues Projekt und wählen Sie den Web Service-Assistenten aus.
Klicken Sie auf den Weiter-Button, und Sie gelangen auf eine Seite, auf der Sie Details zum Webservice und seinem Client angeben müssen. Dies ist die wichtigste Seite bei der Erstellung eines Webservices. Stellen Sie sicher, dass Sie den „Web Service-Typ“ als „Bottom up Java bean Web Service“ auswählen, da wir einen Bottom-up-Ansatz implementieren. Es gibt zwei Möglichkeiten, einen Webservice zu erstellen:
- Contract last oder Bottom-up-Ansatz: Bei diesem Ansatz erstellen wir zuerst die Implementierung und generieren dann die WSDL-Datei daraus. Unsere Implementierung fällt in diese Kategorie.
- Contract first oder Top-Down-Ansatz: Bei diesem Ansatz erstellen wir zuerst den Webservice-Vertrag, d.h. die WSDL-Datei, und erstellen dann die Implementierung dafür.
In der Serviceimplementierung geben Sie den vollständig klassifizierten Pfad der Implementierungsklasse PersonServiceImpl an. Achten Sie darauf, den Schieberegler im Service- und Client-Typ nach links zu bewegen, damit ein Client-Programm generiert werden kann und auch eine Benutzeroberfläche, um unseren Webservice zu testen. Überprüfen Sie die Konfigurationen in der Webservice-Implementierung, Sie sollten korrekte Angaben für Server-Laufzeit, Webservice-Laufzeit und Serviceprojekt machen. Normalerweise werden diese automatisch ausgefüllt, und Sie müssen hier keine Änderungen vornehmen. Für Client-Konfigurationen können Sie den Namen des Clientprojekts nach Belieben angeben. Ich habe es standardmäßig als SOAPExampleClient belassen. Wenn Sie auf den Link für die Webservice-Laufzeit klicken, erhalten Sie verschiedene Optionen, wie im untenstehenden Bild gezeigt. Ich habe es jedoch als Standard belassen.
Klicken Sie auf den Weiter-Button, und dann können Sie die Methoden auswählen, die Sie als Webservice verfügbar machen möchten. Sie können auch den Webservice-Stil als Dokument oder literal auswählen. Sie können den Namen der WSDL-Datei ändern, aber es ist gut, ihn mit dem Namen der Implementierungsklasse zu haben, um später Verwirrung zu vermeiden.
Klicken Sie auf den Weiter-Button, und Sie gelangen auf die Seite zum Starten des Servers. Klicken Sie auf den „Server starten“-Button, und dann wird der Weiter-Button aktiviert.
Klicken Sie auf den Weiter-Button, und Sie gelangen auf eine Seite, um den „Web Services Explorer“ zu starten.
Klicken Sie auf den Start-Button, und es öffnet sich ein neues Fenster im Browser, in dem Sie Ihren Webservice testen können, bevor Sie mit dem Clientanwendungsteil fortfahren. Es sieht aus wie das untenstehende Bild für unser Projekt.
Wir können hier einige grundlegende Tests durchführen, aber für unsere einfache Anwendung bin ich bereit, mit der Erstellung der Clientanwendung fortzufahren. Klicken Sie im Popup-Fenster der Eclipse-Webservices auf den Weiter-Button, und Sie gelangen auf eine Seite für den Quellordner der Clientanwendung.
Klicken Sie auf den Weiter-Button, und Sie erhalten verschiedene Optionen zur Auswahl als Testeinrichtung. Ich gehe voran mit JAX-RPC JSPs, sodass die Clientanwendung eine JSP-Seite generiert, die wir verwenden können.
Beachten Sie die Methoden getEndpoint() und setEndpoint(String), die hinzugefügt wurden und die wir verwenden können, um die URL des Webservice-Endpunkts zu erhalten, und wir können sie auf eine andere URL setzen, falls wir unseren Server auf einen anderen URL-Endpunkt verlegen. Klicken Sie auf den Fertigstellen-Button, und Eclipse erstellt das Clientprojekt in Ihrem Arbeitsbereich, es wird auch die Client-Test-JSP-Seite gestartet, wie unten gezeigt.
Sie können die URL kopieren und in jedem Browser öffnen, den Sie möchten. Testen wir einige der freigegebenen Dienste und sehen uns das Output an.
Eclipse SOAP-Webservice-Test
-
- addPerson
-
- getPerson
-
- getAllPersons
Beachten Sie, dass Personendetails im Ergebnisbereich nicht gedruckt werden, da es sich um automatisch generierten Code handelt, und wir müssen ihn ein wenig überarbeiten, um das gewünschte Output zu erhalten. Öffnen Sie Result.jsp im Clientprojekt, und Sie werden sehen, dass ein Switch-Case verwendet wird, um das Ergebnis zu generieren. Für die getAllPersons()-Methode war es in meinem Fall 42. Beachten Sie, dass es in Ihrem Fall völlig anders sein könnte. Ich habe den Code für Fall 42 wie unten gezeigt geändert.
case 42:
gotMethod = true;
com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons();
if(getAllPersons42mtemp == null){
%>
<%=getAllPersons42mtemp %>
<%
}else{
String tempreturnp43 = null;
if(getAllPersons42mtemp != null){
java.util.List listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp);
//tempreturnp43 = listreturnp43.toString();
for(com.journaldev.jaxws.beans.Person p : listreturnp43){
int id = p.getId();
int age = p.getAge();
String name=p.getName();
%>
<%=id%>::<%=name %>::<%=age %>
<%
}
}
}
break;
Danach erhalten wir das untenstehende Output. Beachten Sie, dass Eclipse hier ein Hot-Deployment durchführt, sodass ich meine Anwendung nicht neu bereitstellen musste.
Es sieht so aus, als ob unser Webservice und die Clientanwendungen gut funktionieren. Stellen Sie sicher, dass Sie sich etwas Zeit nehmen, um sich die auf der Clientseite von Eclipse generierten Stubs genauer anzusehen, um mehr zu verstehen.
SOAP-Webservice WSDL und Konfigurationen
Schließlich werden Sie bemerken, dass die WSDL-Datei im Webprojekt wie unten generiert wird. PersonServiceImpl.wsdl Code:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.journaldev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.journaldev.com" xmlns:intf="https://service.jaxws.journaldev.com" xmlns:tns1="https://beans.jaxws.journaldev.com" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<import namespace="https://beans.jaxws.journaldev.com"/>
<element name="addPerson">
<complexType>
<sequence>
<element name="p" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="addPersonResponse">
<complexType>
<sequence>
<element name="addPersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="deletePerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="deletePersonResponse">
<complexType>
<sequence>
<element name="deletePersonReturn" type="xsd:boolean"/>
</sequence>
</complexType>
</element>
<element name="getPerson">
<complexType>
<sequence>
<element name="id" type="xsd:int"/>
</sequence>
</complexType>
</element>
<element name="getPersonResponse">
<complexType>
<sequence>
<element name="getPersonReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
<element name="getAllPersons">
<complexType/>
</element>
<element name="getAllPersonsResponse">
<complexType>
<sequence>
<element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person"/>
</sequence>
</complexType>
</element>
</schema>
<schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
<complexType name="Person">
<sequence>
<element name="age" type="xsd:int"/>
<element name="id" type="xsd:int"/>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</complexType>
</schema>
</wsdl:types>
<wsdl:message name="addPersonResponse">
<wsdl:part element="impl:addPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsResponse">
<wsdl:part element="impl:getAllPersonsResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonResponse">
<wsdl:part element="impl:deletePersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="addPersonRequest">
<wsdl:part element="impl:addPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonResponse">
<wsdl:part element="impl:getPersonResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getPersonRequest">
<wsdl:part element="impl:getPerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="deletePersonRequest">
<wsdl:part element="impl:deletePerson" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="getAllPersonsRequest">
<wsdl:part element="impl:getAllPersons" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="PersonServiceImpl">
<wsdl:operation name="addPerson">
<wsdl:input message="impl:addPersonRequest" name="addPersonRequest">
</wsdl:input>
<wsdl:output message="impl:addPersonResponse" name="addPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest">
</wsdl:input>
<wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdl:input message="impl:getPersonRequest" name="getPersonRequest">
</wsdl:input>
<wsdl:output message="impl:getPersonResponse" name="getPersonResponse">
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest">
</wsdl:input>
<wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl">
<wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="addPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="addPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="deletePerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="deletePersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="deletePersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getPerson">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getPersonRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getPersonResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getAllPersons">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getAllPersonsRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getAllPersonsResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="PersonServiceImplService">
<wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl">
<wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Wenn Sie es im Design-Modus in Eclipse öffnen, sieht es aus wie das untenstehende Bild.
Sie können auch auf die WSDL-Datei des Webservices im Browser zugreifen, indem Sie ?wsdl an den Webservice-Endpunkt anhängen.
Sie werden auch feststellen, dass web.xml geändert wurde, um Apache Axis als Front-Controller für den Webservice zu verwenden.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SOAPExample</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>Apache-Axis Servlet</display-name>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Axis Admin Servlet</display-name>
<servlet-name>AdminServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/servlet/AdminServlet</url-pattern>
</servlet-mapping>
</web-app>
Das untenstehende Bild zeigt den Webservice und das Clientprojekt mit allen automatisch generierten Stubs und JSP-Seiten zum Testen des Webservices.
Das ist alles für das Beispiel zu SOAP-Webservices in Java mit Eclipse. Wie Sie sehen können, wurde der schwierigste Teil automatisch von Eclipse erledigt, und unser gesamter Fokus lag darauf, die Geschäftslogik für unseren Webservice zu schreiben.