Seifen-Webdienste in Java können auf verschiedene Arten entwickelt werden. Wir haben in unserem letzten Tutorial über JAX-WS SOAP-Webdienste gelernt, heute werden wir lernen, wie wir SOAP-Webdienste und das zugehörige Client-Programm mithilfe von Eclipse erstellen können. Hierbei verwenden wir nicht JAX-WS, sondern Apache Axis, das in Eclipse integriert ist und einen schnellen und einfachen Weg bietet, eine Anwendung in einen Java-Webdienst umzuwandeln und Client-Stubs mit einer Test-JSP-Seite für Testzwecke zu erstellen.
SOAP-Webdienste 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 außerdem sicher, dass Sie Apache Tomcat oder einen anderen Servlet-Container als Server in Eclipse hinzugefügt haben. Lassen Sie uns jetzt mit unserer Eclipse-Webdienst-Implementierung beginnen.
Beispiel für einen SOAP-Webdienst
Lassen Sie uns mit unserem Beispiel für einen SOAP-Webdienst in Eclipse beginnen. Zunächst erstellen wir ein einfaches Dynamic Web Project in Eclipse, das die Geschäftslogik für unsere Anwendung enthält. Klicken Sie auf die Schaltfläche „Weiter“ oben, und Sie gelangen zur nächsten Seite, um den Namen Ihres Webprojekts und Target Runtime anzugeben. Beachten Sie, dass ich Apache Tomcat 8 verwende; Sie können auch einen anderen standardmäßigen Servlet-Container verwenden.
Klicken Sie auf „Weiter“, und Sie werden aufgefordert, „Context Root“ und den Speicherort des Inhaltsverzeichnisses anzugeben. Sie können sie als Standard belassen.
Klicken Sie auf „Fertigstellen“, und Eclipse erstellt das Projektgerüst für Sie. Lassen Sie uns mit unserer Geschäftslogik beginnen. Für unser Beispiel möchten wir einen Webdienst veröffentlichen, der zum Hinzufügen/Löschen/Abrufen eines Objekts verwendet werden kann. Der erste Schritt besteht also darin, eine Model-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 ein einfacher Java Bean ist, wir implementieren das Serializable
Interface, weil wir es über das Netzwerk transportieren werden. Wir haben auch eine Implementierung der Methode toString
bereitgestellt, die verwendet wird, wenn wir dieses Objekt auf der Clientseite drucken. Der nächste Schritt besteht darin, Service-Klassen zu erstellen, sodass wir eine Schnittstelle namens PersonService
und deren einfache Implementierungsklasse PersonServiceImpl
haben werden.
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();
}
Untenstehend ist die Implementierung der Service-Klasse, wir verwenden eine Map, um Person-Objekte als Datenquelle zu speichern. In der realen Programmierung möchten 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<Integer> 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 war es für unsere Geschäftslogik, da wir diese in einem Webdienst verwenden werden, hat es keinen Sinn, hier Webseiten zu erstellen. Beachten Sie, dass wir keinen Bezug zu irgendwelchen Webdienst-Klassen im obigen Code haben.
SOAP-Webdienste in Java mit Eclipse
Sobald unsere Geschäftslogik bereit ist, ist der nächste Schritt, Eclipse zu verwenden, um eine Web Service-Anwendung zu erstellen. Erstellen Sie ein neues Projekt und wählen Sie den Web Service-Assistenten aus. Klicken Sie auf die Schaltfläche „Weiter“, und Sie gelangen zu einer Seite, auf der die Details des Webdienstes und seines Clients angegeben werden müssen. Dies ist die wichtigste Seite bei der Erstellung eines Webdienstes. Stellen Sie sicher, dass Sie „Web Service-Typ“ als „Bottom-up-Java-Bean-Webdienst“ auswählen, da wir mit dem Bottom-up-Ansatz arbeiten. Es gibt zwei Möglichkeiten, einen Webdienst zu erstellen:
- Vertragslast oder Bottom-up-Ansatz: Bei diesem Ansatz erstellen wir zunächst die Implementierung und generieren dann die WSDL-Datei daraus. Unsere Implementierung fällt in diese Kategorie.
- Vertragszuerst oder Top-Down-Ansatz: Bei diesem Ansatz erstellen wir zunächst den Webdienstvertrag, d. h. die WSDL-Datei, und erstellen dann die Implementierung dafür.
In der Dienstimplementierung geben Sie den vollständig qualifizierten Pfad der Implementierungsklasse
PersonServiceImpl
an. Stellen Sie sicher, dass Sie den Schieberegler für den Dienst- und Client-Typ nach links bewegen, damit er ein Client-Programm generieren und auch die Benutzeroberfläche zum Testen unseres Webdienstes bereitstellen kann. Überprüfen Sie die Konfigurationen in der Webdienstimplementierung. Hier sollten Sie die korrekten Details für Serverlaufzeit, Webdienstlaufzeit und Dienstprojekt angeben. Normalerweise werden sie automatisch ausgefüllt und Sie müssen hier keine Änderungen vornehmen. Für die Client-Konfiguration können Sie den Namen des Client-Projekts wie gewünscht angeben. Ich habe es auf den Standardwert SOAPExampleClient
belassen. Wenn Sie auf den Link für die Webdienstlaufzeit klicken, erhalten Sie verschiedene Optionen, wie im folgenden Bild gezeigt. Ich habe es jedoch auf den Standardwert belassen. Klicken Sie auf die Schaltfläche „Weiter“ und Sie können die Methoden auswählen, die Sie als Webdienst freigeben möchten. Sie können auch den Webdienststil als Dokument oder Literal auswählen. Sie können den Namen des WSDL-Dokuments ändern, aber es ist gut, ihn mit dem Namen der Implementierungsklasse zu haben, um spätere Verwirrungen zu vermeiden.
Klicken Sie auf die Schaltfläche „Weiter“ und Sie gelangen zur Serverstartseite. Klicken Sie auf die Schaltfläche „Server starten“ und dann wird die nächste Schaltfläche aktiviert.
Klicken Sie auf die Schaltfläche „Weiter“ und Sie gelangen zu einer Seite zum Starten des „Web Services Explorer“.
Klicken Sie auf die Schaltfläche „Starten“ und es wird ein neues Fenster im Browser geöffnet, in dem Sie Ihren Webdienst testen können, bevor Sie mit dem Client-Anwendungsteil fortfahren. Es sieht aus wie im folgenden Bild für unser Projekt.
Hier können wir einige Tests durchführen, aber für unsere einfache Anwendung bin ich bereit, mit der Erstellung der Client-Anwendung fortzufahren. Klicken Sie auf die Schaltfläche „Weiter“ im Eclipse-Webdienste-Popup-Fenster und Sie gelangen zu einer Seite für den Quellordner für die Client-Anwendung.
Klicken Sie auf die Schaltfläche „Weiter“ und Sie erhalten verschiedene Optionen zur Auswahl als Testeinrichtung. Ich gehe mit JAX-RPC JSPs vor, damit die Client-Anwendung eine JSP-Seite generiert, die wir verwenden können.
Beachten Sie die hinzugefügten Methoden
getEndpoint()
und setEndpoint(String)
, die wir verwenden können, um die Webdienst-Endpunkt-URL abzurufen und sie auf eine andere URL festzulegen, falls wir unseren Server an einen anderen Endpunkt-URL verschieben. Klicken Sie auf die Schaltfläche „Fertig stellen“ und Eclipse erstellt das Client-Projekt in Ihrem Workspace und startet auch die Client-Test-JSP-Seite, wie unten gezeigt. Sie können die URL kopieren und in jedem gewünschten Browser öffnen. Testen wir einige der freigegebenen Dienste und sehen wir die Ausgabe.
Eclipse SOAP-Webdiensttest
-
getAllPersons
Beachten Sie, dass Personendetails nicht im Ergebnisbereich angezeigt werden. Dies liegt daran, dass es sich um automatisch generierten Code handelt und wir ihn ein wenig umstrukturieren müssen, um das gewünschte Ergebnis zu erzielen. Öffnen Sie Result.jsp im Client-Projekt und Sie werden sehen, dass dort ein Switch-Case verwendet wird, um das Ergebnis auszugeben. Für die Methode getAllPersons() war es in meinem Fall Fall 42. Beachten Sie, dass es in Ihrem Fall völlig anders sein kann. 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<com.journaldev.jaxws.beans.Person> 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 folgende Ausgabe. Beachten Sie, dass Eclipse hier ein Hot-Deployment durchführt, sodass ich meine Anwendung nicht neu bereitstellen musste.
Es scheint, als ob unser Webdienst und die Clientanwendungen gut funktionieren. Nehmen Sie sich Zeit, um die vom Eclipse generierten Stub-Dateien auf der Clientseite genauer zu betrachten und zu verstehen.
SOAP-Webdienst-WSDL und Konfigurationen
Zuletzt werden Sie feststellen, dass in dem Webdienstprojekt die WSDL-Datei wie folgt 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 created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<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 Designmodus in Eclipse öffnen, wird es wie im folgenden Bild aussehen. Sie können auch auf die WSDL-Datei des Webservices über den Browser zugreifen, indem Sie ?wsdl an das Ende des Webservice-Endpunkts anhängen.
Sie werden auch feststellen, dass die web.xml-Datei 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 folgende Bild zeigt den Webservice- und Client-Projekt mit allen automatisch generierten Stubs und JSP-Seiten zum Testen des Webservices.
Das war alles für SOAP-Webservices im Java-Beispiel mit Eclipse. Wie Sie sehen können, wurde der gesamte schwierige Teil automatisch von Eclipse erledigt und unser Fokus lag darauf, die Geschäftslogik für unseren Webservice zu schreiben.
Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse