1. Überblick
Java-API für XML-Webdienste (JAX-WS) ist eine standardisierte API zum Erstellen und Verwenden von SOAP-Webdiensten (Simple Object Access Protocol).
In diesem Artikel erstellen wir einen SOAP-Webdienst und stellen eine Verbindung mit JAX-WS her.
2. SEIFE
SOAP ist eine XML-Spezifikation zum Senden von Nachrichten über ein Netzwerk.
SOAP ist XML-schwer und kann daher am besten mit Tools/Frameworks verwendet werden. JAX-WS ist ein Framework, das die Verwendung von SOAP vereinfacht. Es ist Teil des Standard-Java.
3. Top-Down vs. Bottom-Up
Es gibt zwei Möglichkeiten, SOAP-Webdienste zu erstellen. Wir können einen Top-Down-Ansatz oder einen Bottom-Up-Ansatz wählen.
Bei einem Top-Down-Ansatz (Vertrag zuerst) wird ein WSDL-Dokument erstellt und die erforderlichen Java-Klassen werden aus der WSDL generiert. In einem Bottom-up-Ansatz (letzter Kontrakt)
Da Ihre WSDL jedoch aus den Java-Klassen generiert wird, kann jede Änderung des Codes zu einer Änderung der WSDL führen. Dies ist beim Top-Down-Ansatz nicht der Fall.
4. Web Services Definition Language (WSDL)
WSDL ist eine Vertragsdefinition der verfügbaren Dienste. Es ist eine Spezifikation von Eingabe-/Ausgabemeldungen und wie der Webdienst aufgerufen wird. Es ist sprachneutral und in XML definiert.
Schauen wir uns die wichtigsten Elemente eines WSDL-Dokuments an.
4.1. Definitionen
Das definitions -Element ist das Wurzelelement aller WSDL-Dokumente. Sie definiert den Namen, den Namespace usw. des Dienstes und kann, wie Sie sehen, recht umfangreich sein:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://jaxws.baeldung.com/"
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
xmlns:wsp="http://www.w3.org/ns/ws-policy"
xmlns:wsp1__2="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://jaxws.baeldung.com/"
name="EmployeeService">
...
</definitions>
4.2. Typen
Das types -Element definiert die vom Web-Service verwendeten Datentypen. WSDL verwendet XSD (XML Schema Definition) als das Typsystem, das bei der Interoperabilität hilft:
<definitions ...>
...
<types>
<xsd:schema>
<xsd:import namespace="http://jaxws.baeldung.com/"
schemaLocation = "http://localhost:8080/employeeservice?xsd=1"/>
</xsd:schema>
</types>
...
</definitions>
4.3. Mitteilungen
Das message -Element liefert eine abstrakte Definition der übertragenen Daten. Jedes message -Element beschreibt die Eingabe oder Ausgabe einer Servicemethode und die möglichen Ausnahmen:
<definitions ...>
...
<message name="getEmployee">
<part name="parameters" element="tns:getEmployee"/>
</message>
<message name="getEmployeeResponse">
<part name="parameters" element="tns:getEmployeeResponse"/>
</message>
<message name="EmployeeNotFound">
<part name="fault" element="tns:EmployeeNotFound"/>
</message>
...
</definitions>
4.4. Vorgänge und Anschlusstypen
Das portType -Element beschreibt jede auszuführende operation und alle betroffenen message -Elemente. Die Operation getEmployee gibt beispielsweise die Anforderung input , output und eine mögliche fault -Ausnahme an, die vom Webdienst operation ausgelöst wird:
<definitions ...>
...
<portType name="EmployeeService">
<operation name="getEmployee">
<input
wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployeeRequest"
message="tns:getEmployee"/>
<output
wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployeeResponse"
message="tns:getEmployeeResponse"/>
<fault message="tns:EmployeeNotFound" name="EmployeeNotFound"
wsam:Action="http://jaxws.baeldung.com/EmployeeService/getEmployee/Fault/EmployeeNotFound"/>
</operation>
....
</portType>
...
</definitions>
4.5. Bindungen
Das binding -Element enthält Protokoll- und Datenformatdetails für jeden portType :
<definitions ...>
...
<binding name="EmployeeServiceImplPortBinding"
type="tns:EmployeeService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="getEmployee">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="EmployeeNotFound">
<soap:fault name="EmployeeNotFound" use="literal"/>
</fault>
</operation>
...
</binding>
...
</definitions>
4.6. Dienste und Häfen
Das service -Element definiert die vom Web-Service unterstützten Ports.
Das port -Element in service definiert den name , binding und die address des Dienstes:
<definitions ...>
...
<service name="EmployeeService">
<port name="EmployeeServiceImplPort"
binding="tns:EmployeeServiceImplPortBinding">
<soap:address
location="http://localhost:8080/employeeservice"/>
</port>
</service>
...
</definitions>
5. Top-Down-Ansatz (Vertrag zuerst)
Beginnen wir mit einem Top-Down-Ansatz, indem Sie eine WSDL-Datei employeeservicetopdown.wsdl. erstellen. Der Einfachheit halber gibt es nur eine Methode:
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://topdown.server.jaxws.baeldung.com/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://topdown.server.jaxws.baeldung.com/"
qname="EmployeeServiceTopDown">
<types>
<xsd:schema
targetNamespace="http://topdown.server.jaxws.baeldung.com/">
<xsd:element name="countEmployeesResponse" type="xsd:int"/>
</xsd:schema>
</types>
<message name="countEmployees">
</message>
<message name="countEmployeesResponse">
<part name="parameters" element="tns:countEmployeesResponse"/>
</message>
<portType name="EmployeeServiceTopDown">
<operation name="countEmployees">
<input message="tns:countEmployees"/>
<output message="tns:countEmployeesResponse"/>
</operation>
</portType>
<binding name="EmployeeServiceTopDownSOAP"
type="tns:EmployeeServiceTopDown">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<operation name="countEmployees">
<soap:operation
soapAction="http://topdown.server.jaxws.baeldung.com/ EmployeeServiceTopDown/countEmployees"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="EmployeeServiceTopDown">
<port name="EmployeeServiceTopDownSOAP"
binding="tns:EmployeeServiceTopDownSOAP">
<soap:address
location="http://localhost:8080/employeeservicetopdown"/>
</port>
</service>
</definitions>
5.1. Web Service-Quelldateien aus WSDL generieren
Um Web-Service-Quelldateien aus einem WSDL-Dokument zu generieren, können Sie das Tool wsimport verwenden, das Teil des JDK ist (unter $ JAVA__HOME /bin).
Von der Eingabeaufforderung:
wsimport -s . -p com.baeldung.jaxws.server.topdown employeeservicetopdown.wsdl
Verwendete Befehlszeilenoptionen: -p gibt das Zielpaket an. -s gibt an, wo die generierten Quelldateien abgelegt werden sollen.
Die generierten Dateien:
-
EmployeeServiceTopDown.java - ist die Service-Endpunktschnittstelle
(SEI), das Methodendefinitionen enthält ** ObjectFactory.java - enthält Factory-Methoden zum Erstellen von Instanzen
Schema abgeleitete Klassen programmgesteuert ** EmployeeServiceTopDown Service.java__ - ist die Service Provider-Klasse
das kann von einem JAX-WS-Client verwendet werden
5.2. Web Service Endpoint Interface
Das wsimport -Tool hat die Web-Service-Endpunktschnittstelle EmployeeServiceTopDown generiert. Darin werden die Webdienstmethoden angegeben:
@WebService(
name = "EmployeeServiceTopDown",
targetNamespace = "http://topdown.server.jaxws.baeldung.com/")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
ObjectFactory.class
})
public interface EmployeeServiceTopDown {
@WebMethod(
action = "http://topdown.server.jaxws.baeldung.com/"
+ "EmployeeServiceTopDown/countEmployees")
@WebResult(
name = "countEmployeesResponse",
targetNamespace = "http://topdown.server.jaxws.baeldung.com/",
partName = "parameters")
public int countEmployees();
}
5.3. Web Service Implementierung
Das wsimport -Tool hat die Struktur des Web-Service erstellt. Wir müssen die Implementierung des Webservices erstellen:
@WebService(
name = "EmployeeServiceTopDown",
endpointInterface = "com.baeldung.jaxws.server.topdown.EmployeeServiceTopDown",
targetNamespace = "http://topdown.server.jaxws.baeldung.com/")
public class EmployeeServiceTopDownImpl
implements EmployeeServiceTopDown {
@Inject
private EmployeeRepository employeeRepositoryImpl;
@WebMethod
public int countEmployees() {
return employeeRepositoryImpl.count();
}
}
6. Bottom-Up (Contract-Last) -Ansatz
In einem Bottom-up-Ansatz müssen wir sowohl die Endpunktschnittstelle als auch die Implementierungsklassen erstellen. Die WSDL wird aus den Klassen generiert, wenn der Webdienst veröffentlicht wird.
Erstellen Sie einen Webdienst, der einfache CRUD-Vorgänge für Employee -Daten ausführt.
6.1. Die Modellklasse
Die Employee -Modellklasse:
public class Employee {
private int id;
private String firstName;
//standard getters and setters
}
6.2. Web Service Endpoint Interface
Die Web-Service-Endpunkt-Schnittstelle, die die Web-Service-Methoden deklariert:
@WebService
public interface EmployeeService {
@WebMethod
Employee getEmployee(int id);
@WebMethod
Employee updateEmployee(int id, String name);
@WebMethod
boolean deleteEmployee(int id);
@WebMethod
Employee addEmployee(int id, String name);
//...
}
Diese Schnittstelle definiert einen abstrakten Vertrag für den Webservice. Die verwendeten Anmerkungen:
**
**
-
@ WebResult wird verwendet, um den Namen des XML-Elements anzupassen
repräsentiert den Rückgabewert
6.3. Web Service Implementierung
Die Implementierungsklasse der Web-Service-Endpunktschnittstelle:
@WebService(endpointInterface = "com.baeldung.jaxws.EmployeeService")
public class EmployeeServiceImpl implements EmployeeService {
@Inject
private EmployeeRepository employeeRepositoryImpl;
@WebMethod
public Employee getEmployee(int id) {
return employeeRepositoryImpl.getEmployee(id);
}
@WebMethod
public Employee updateEmployee(int id, String name) {
return employeeRepositoryImpl.updateEmployee(id, name);
}
@WebMethod
public boolean deleteEmployee(int id) {
return employeeRepositoryImpl.deleteEmployee(id);
}
@WebMethod
public Employee addEmployee(int id, String name) {
return employeeRepositoryImpl.addEmployee(id, name);
}
//...
}
7. Veröffentlichen der Web-Service-Endpunkte
Um die Webservices (Top-Down und Bottom-Up) zu veröffentlichen, müssen wir eine Adresse und eine Instanz der Webservice-Implementierung an die publish () -Methode der Klasse javax.xml.ws.Endpoint übergeben:
public class EmployeeServicePublisher {
public static void main(String[]args) {
Endpoint.publish(
"http://localhost:8080/employeeservicetopdown",
new EmployeeServiceTopDownImpl());
Endpoint.publish("http://localhost:8080/employeeservice",
new EmployeeServiceImpl());
}
}
Wir können jetzt EmployeeServicePublisher ausführen, um den Webdienst zu starten. Um CDI-Funktionen nutzen zu können, können die Webservices als WAR-Datei auf Anwendungsservern wie WildFly oder GlassFish bereitgestellt werden.
8. Remote-Webdienst-Client
Erstellen Sie jetzt einen JAX-WS-Client, um eine Remote-Verbindung zum EmployeeService -Webdienst herzustellen.
8.1. Client-Artefakte generieren
Um JAX-WS-Client-Artefakte zu generieren, können Sie erneut das wsimport -Tool verwenden:
wsimport -keep -p com.baeldung.jaxws.client http://localhost:8080/employeeservice?wsdl
Die generierte Klasse EmployeeService Service kapselt die Logik, um den Serverport mithilfe von URL und QName__ abzurufen.
8.2. Verbindung zum Web Service
Der Webdienstclient verwendet den generierten EmployeeService Service__, um eine Verbindung zum Server herzustellen und Webdienstaufrufe aus der Ferne durchzuführen:
public class EmployeeServiceClient {
public static void main(String[]args) throws Exception {
URL url = new URL("http://localhost:8080/employeeservice?wsdl");
EmployeeService__Service employeeService__Service
= new EmployeeService__Service(url);
EmployeeService employeeServiceProxy
= employeeService__Service.getEmployeeServiceImplPort();
List<Employee> allEmployees
= employeeServiceProxy.getAllEmployees();
}
}
9. Fazit
Dieser Artikel ist eine schnelle Einführung in SOAP-Webdienste mit JAX-WS .
Wir haben sowohl Bottom-Up- als auch Top-Down-Ansätze verwendet, um SOAP-Webdienste mithilfe der JAX-WS-API zu erstellen. Wir haben auch einen JAX-WS-Client geschrieben, der sich remote mit dem Server verbinden und Webdienstanrufe durchführen kann.
Der vollständige Quellcode ist verfügbar unter over auf GitHub .