Angewandte Netzwerktechnik kompakt

Material zum Buch

SOAP, RESTful, Eigenbau Webservices


Für die Übungen und eigene Experimente stellt die Webseite verschiedene Webservices bereit. Diese können über die folgende Seite beobachtet werden.

zu Kapitel 11.1 (Eigenbau)


Für Kapitel 11.1 stehen uns die Klassen TCPClient, für den Client und TCPServer, Befehl, ClientHandler, für den Server zur Verfügung.

Client und Server kommunizieren über ein selbst definiertes TCP/IP-Protokoll. Dieses verwendet keinen DataOutputStream sondern eine textuelle Codierung als UTF-8 String, um plattformunabhängig zu sein.

zu Kapitel 11.4 (SOAP Service)


Zu diesem Kapitel gibt es folgende Projekte:

zu Kapitel 11.6 (RESTful Service Server)


Auch in diesem Kapitel gibt es mehrere Projekte:

Zur Verwendung der Server Klassen wird eine Bibliothek Jersey benötigt, welche unter https://jersey.github.io/ abrufbar ist. Alle benötigten Verweise sind bereits in der Klasse vorhanden. Abbildung 9.5 im Buch zeigt, wie die Bibliothek zu einem Eclipse-Projekt hinzugefügt werden kann.

zu Kapitel 11.6.2.1 (REST Aufruf über HTML)


In den Formularen wird gezeigt wie ein REST Webservice über HTML Formular aus dem Browser aufgerufen werden kann.




zu Kapitel 11.6.2.2 und 11.6.3 (RESTful Service Clients)


Auch in diesem Kapitel gibt es mehrere Projekte:

Die passenden Server Klassen stehen in Kapitel 11.6.1.

zu Kapitel 11.7 (Gegenüberstellung)


Im diesem ZIP-Archiv befinden sich die Wireshark-Aufzeichnungen zu Kapitel 9.6 mit der Kommunikation zwischen Client und Server für SOAP, REST und Eigenbau Webservice.

Vorschau der Java-Klassen zu Kapitel 11.1


TCPClient.java

package kap11_1.TcpProtokollClient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.Charset;

import kap11_1.TcpProtokollServer.Befehl;
import studierende.Leistung;

public class TCPClient 
{
	String ip;
	int port;
	Socket server;
	OutputStream outToServer;
	InputStream inFromServer;

	public TCPClient(String ip, int port)
	{
		this.ip = ip;
		this.port = port;
	}

	public void baueVerbindungAuf() throws UnknownHostException, IOException
	{
		this.server = new Socket(ip, port);

		System.out.println("Client verbunden mit: " + this.server.getInetAddress() + ":" + this.server.getPort());

		this.outToServer = this.server.getOutputStream();
		this.inFromServer = this.server.getInputStream();
	}

	public Befehl sendeBefehl(Befehl befehl) throws IOException
	{
		byte[] bytes = new byte[6];
		Befehl antwort = new Befehl();

		outToServer.write(befehl.baueBefehlString());

		int read = inFromServer.read(bytes, 0, 6);
		if(read == -1)
		{
			schliesseVerbindung();
			return antwort;
		}
		antwort.setAnfrage(new String(bytes, 0, 3, Charset.forName("ASCII")));
		String antwortAnhangLaenge = new String(bytes, 3, 3, Charset.forName("ASCII"));

		int anhangLaenge = Integer.parseInt(antwortAnhangLaenge);
		if(anhangLaenge > 0)
		{
			bytes = new byte[anhangLaenge];
			inFromServer.read(bytes, 0, anhangLaenge);
			antwort.setAnhang(new String(bytes, 0, anhangLaenge, Charset.forName("UTF-8")));
		}
		return antwort;
	}

	public void schliesseVerbindung() throws IOException
	{
		outToServer.close();
		inFromServer.close();
		server.close();
	}

	public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException
	{
		String ip =  "localhost";
		int port  =  47331;
		String name = "Mia Fischer";
		
		TCPClient client = new TCPClient(ip, port);

		client.baueVerbindungAuf();

		// Finde Matrikelnummer zu Name 
		Befehl befehl = new Befehl(); 
		befehl.setAnfrage("MAT");
		befehl.setAnhang(name);
		Befehl antwort = client.sendeBefehl(befehl);
		if(antwort.getAnhang().length() > 0)
		{
			// Martikelnummer zu Name gefunden (Student vorhanden)
			int matrikelNummer = Integer.parseInt(antwort.getAnhang());
			System.out.println("Matrikelnummer zu " + name + " ist: "+ matrikelNummer);

			// Leistungen des Studenten landen
			befehl.setAnfrage("LEI");
			befehl.setAnhang(String.format("%03d", matrikelNummer));
			antwort = client.sendeBefehl(befehl); 

			String elemente[] = antwort.getAnhang().split("\\|");
			Leistung leistungen[] = new Leistung[elemente.length];
			for(int i = 0; i < leistungen.length; i++)
			{
				String teile[] = elemente[i].split(";");
				leistungen[i] = new Leistung();
				leistungen[i].modul = teile[0];
				leistungen[i].note = Double.parseDouble(teile[1]);
				System.out.println(leistungen[i].modul + " " + leistungen[i].note);
			}
		}
		else 
			System.out.println("Matrikelnummer zu " + name + " nicht gefunden");

		client.schliesseVerbindung();
	}
}

Befehl.java

package kap11_1.TcpProtokollServer;

import java.io.UnsupportedEncodingException;

public class Befehl 
{
	String anfrage = "";
	String anhang  = "";

	public String getAnhang() {
		return anhang;
	}

	public void setAnhang(String anhang) {
		this.anhang = anhang;
	}

	public String getAnfrage() {
		return anfrage;
	}

	public void setAnfrage(String anfrage) {
		this.anfrage = anfrage;
	}

	public byte[] baueBefehlString() throws UnsupportedEncodingException
	{
		// Speicher fuer die Teile des Befehls
		// 3 Bytes fuer die Anfrage im 7Bit Ascii-Code
		byte[] anfrageBytes = anfrage.getBytes("ASCII");
		// Bytes fuer den Parameter im 8/16/32Bit UTF-8 Code
		byte[] anhangBytes = anhang.getBytes("UTF-8");
		// 3 Bytes fuer die Zeichenkette der Laenge im 7Bit Ascii-Code
		byte[] lengthBytes =  String.format("%03d", anhangBytes.length).getBytes("ASCII");
		
		// Zielarray in entsprechender Groesse anlegen
		byte[] befehlBytes = new byte[3 + 3 + anhangBytes.length];
		
		// umkopieren in Zielarray
		int index = 0;
		for(int i=0; i < anfrageBytes.length; i++)
			befehlBytes[index++] = anfrageBytes[i];
		for(int i=0; i < lengthBytes.length; i++)
			befehlBytes[index++] = lengthBytes[i];
		for(int i=0; i < anhangBytes.length; i++)
			befehlBytes[index++] = anhangBytes[i];
		
		return befehlBytes;
	}
}

ClientHandler.java

package kap11_1.TcpProtokollServer;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.Charset;

import studierende.Speicher;
import studierende.Student;
import studierende.Leistung;

public class ClientHandler extends Thread
{
	Socket clientSocket;
	InputStream inFromClient;
	OutputStream outToClient;

	public ClientHandler(Socket clientSocket) throws IOException
	{
		this.clientSocket = clientSocket;
		this.inFromClient = clientSocket.getInputStream();
		this.outToClient = clientSocket.getOutputStream();
	}

	@Override
	public void run()
	{
		while(true)
		{
			try 
			{
				byte[] bytes = new byte[6];

				int read = inFromClient.read(bytes, 0, 6);
				if(read == -1)
				{
					schliesseVerbindung();
					return;
				}

				Befehl befehl = new Befehl();

				befehl.anfrage = new String(bytes, 0, 3, Charset.forName("ASCII"));
				String anhangLaenge = new String(bytes, 3, 3, Charset.forName("ASCII"));

				int laenge = Integer.parseInt(anhangLaenge);
				if(laenge > 0)
				{
					bytes = new byte[laenge];
					inFromClient.read(bytes, 0, laenge);
					befehl.anhang = new String(bytes, 0, laenge, Charset.forName("UTF-8"));
				}
				System.out.println("Kommando: " + befehl.anfrage + " " + befehl.anhang + 
						" von " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
			
				if(befehl.anfrage.contains("MAT"))
				{
					Befehl antwort = new Befehl();
					antwort.anfrage = "ANT";
					
					Student myStudent= Speicher.getSucheMatrikelNummerZuName(befehl.anhang);
					if(myStudent != null)
					{
						antwort.anhang = String.valueOf(myStudent.matrikelNummer); 
					}
					outToClient.write(antwort.baueBefehlString());
				}
				else if(befehl.anfrage.contains("STU"))
				{
					Befehl antwort = new Befehl();
					antwort.anfrage = "ANT";
					int matrikelNummer = Integer.parseInt(befehl.anhang);
					
					Student myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
					if(myStudent != null)
					{
						antwort.anhang = myStudent.matrikelNummer + ";" + myStudent.name; 
					}
					outToClient.write(antwort.baueBefehlString());
				}
				else if(befehl.anfrage.contains("LEI"))
				{
					Befehl antwort = new Befehl();
					antwort.anfrage = "ANT";
					int matrikelNummer = Integer.parseInt(befehl.anhang);

					Student myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
					if(myStudent != null)
					{
						if(myStudent.leistungen != null)
						{
							for(Leistung l: myStudent.leistungen)
							{
								antwort.anhang += l.modul + ";" + l.note + "|";
							}
						}
					}
					outToClient.write(antwort.baueBefehlString());
				}
			}
			catch (Exception e) 
			{
				if(!clientSocket.isConnected())
				{
					try 
					{
						schliesseVerbindung();
					} 
					catch (IOException e1) 
					{
						e1.printStackTrace();
					}
				}
				e.printStackTrace();
				return;
			}
		}
	}

	public void schliesseVerbindung() throws IOException
	{
		System.out.println("Verbindung beendet " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
		outToClient.close();
		inFromClient.close();
		clientSocket.close();
	}
}

TCPServer.java

package kap11_1.TcpProtokollServer;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer 
{
	public static void main(String[] args) throws IOException
	{
		int port = 47331;

		// ServerSocket erzeugen
		ServerSocket serverSocket = new ServerSocket(port);
		System.out.println("Warte auf Verbindung auf "+InetAddress.getLocalHost() +":" + port);

		while(true)
		{
			// Auf Verbindung warten
			Socket clientSocket = serverSocket.accept();
			System.out.println("Client verbunden: " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());

			// Thread zur Berabeitung der Anfragen ueber diese Verbindung starten
			ClientHandler clientHandler = new ClientHandler(clientSocket);
			clientHandler.start();
		}
	}
}

Vorschau der Java-Klassen zu Kapitel 11.4


SoapClient.java

package kap11_3.soapClient;

import java.net.URL;

import jakarta.xml.ws.Service;
import javax.xml.namespace.QName;

// Beschreibung der Server-Schnittstelle
import soap.Leistung;
import soap.VerwaltungInterface;

public class SoapClient 
{
	public static void main(String[] args) throws Throwable 
	{
		// URL des Servers
		// Eigener Server
		String url ="http://localhost:4434/verwaltung";
		// Server von Webseite
		//String url = "http://angewnwt-neu.hof-university.de:4437/verwaltung";
		
		// Name des Studenten, fuer den wir anfragen
		String name = "Hannah Becker";

		// Verbindung zum Server aufbauen
		Service service = Service.create(
				new URL(url + "?wsdl"), 
				new QName("http://soapServer.kap9_3/", "VerwaltungImplService"));

		// Stub-Methoden bereitstellen
		VerwaltungInterface verwaltung = service.getPort(VerwaltungInterface.class);

		// Server abfragen: 1) Matrikelnummer zu Name
		int matrikelNummer = verwaltung.martikelnummerZuName(name);
		System.out.println("\nMartikelNummer: " + matrikelNummer);

		if (matrikelNummer != -1) 
		{
			// Server abfragen: 2) leistungen zur Matrikelnummer
			Leistung[] leistungen = verwaltung.studienleistungZuMartikelnummer(matrikelNummer);

			if (leistungen != null) 
			{
				System.out.println(leistungen); 
				
				for (Leistung leistung : leistungen) 
				{
					System.out.println("\nLeistung: " + leistung.getModul() + " - " + leistung.getNote());
				}
			}
		}
	}
}

soapClientExceptionReturnValue.java

package kap11_3.soapClient;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;
import jakarta.xml.ws.Service;
import jakarta.xml.ws.WebServiceException;

import soap.Leistung;
import soap.VerwaltungInterface;

public class soapClientExceptionReturnValue
{
	public static void main(String[] args) throws MalformedURLException, InterruptedException 
	{
		// URL des Servers
		String url ="http://localhost:4434/verwaltung";
		// Name des Studenten, fuer den wir anfragen
		String name = "Mia Bauer";

		VerwaltungInterface verwaltung = null;

		//FALL 1: Fehler beim Verbindungsaufbau
		boolean serviceErzeugt = false;
		while(!serviceErzeugt) {
			try {
				// Verbindung zum Server aufbauen
				Service service = Service.create(
						new URL(url + "?wsdl"),
						new QName("http://soapServer/", "VerwaltungImplService"));

				// Stub-Methoden bereitstellen
				verwaltung = service.getPort(VerwaltungInterface.class);
				serviceErzeugt=true;
			} catch (WebServiceException e) {
				System.err.println("Server nicht erreichbar! Aufbau der Verbindung wird erneut versucht");
				System.err.println(e);
				Thread.sleep(10000); // vor dem naechsten Versuch kurz warten 
			}
		}

		//FALL 2: Fehler waehrend Anfrage
		if (verwaltung != null) {
			int matrikelNummer = -1;
			boolean anfrageOK;

			anfrageOK = false;
			while(!anfrageOK) {
				try {
					// Server abfragen: 1) Matrikelnummer zu Name
					matrikelNummer = verwaltung.martikelnummerZuName(name);
					System.out.println("\nMartikelNummer: " + matrikelNummer);
					anfrageOK=true;

					if(matrikelNummer != -1) {
						Leistung[] leistungen = null;
						anfrageOK = false;
						// Server abfragen: 2) leistungen zur Matrikelnummer
						leistungen = verwaltung.studienleistungZuMartikelnummer(matrikelNummer);
						anfrageOK=true;

						if (leistungen != null) {
							for (Leistung leistung : leistungen) {
								System.out.println("\nLeistung: " + leistung.getModul() + " - " + leistung.getNote());
							}
						}
					}
				} 
				catch (WebServiceException e) {
					System.err.println("Server nicht erreichbar! Aufbau der Verbindung wird erneut versucht");
					System.err.println(e);
					Thread.sleep(10000); // vor dem naechsten Versuch kurz warten 
				}
			}
		}
	}
}

soapClientException.java

package kap11_3.soapClientException;

import java.net.URL;

import javax.xml.namespace.QName;
import jakarta.xml.ws.Service;
import jakarta.xml.ws.WebServiceException;
import jakarta.xml.ws.http.HTTPException;
import jakarta.xml.ws.soap.SOAPFaultException;
import kap11_3.soapServerException.VerwaltungInterfaceException;
import soap.Leistung;

public class soapClientException 
{
	public static void main(String[] args) throws Exception
	{
		// URL des Servers
		String url ="http://localhost:4434/verwaltung";
		// Name des Studenten, fuer den wir anfragen
		String name = "Hannah BeckerA";

		VerwaltungInterfaceException verwaltung = null;

		//FALL 1: Fehler beim Verbindungsaufbau
		boolean serviceErzeugt = false;
		while(!serviceErzeugt) {
			try {
				// Verbindung zum Server aufbauen
				Service service = Service.create(
						new URL(url + "?wsdl"),
						new QName("http://soapServerException/", "VerwaltungImplExceptionService"));

				// Stub-Methoden bereitstellen
				verwaltung = service.getPort(VerwaltungInterfaceException.class);
				serviceErzeugt=true;
			} catch (WebServiceException e) {
				System.err.println("Server nicht erreichbar! Aufbau der Verbindung wird erneut versucht");
				System.err.println(e);
				Thread.sleep(10000); // vor dem naechsten Versuch kurz warten 
			}
		}

		//FALL 2: Fehler waehrend Anfrage
		if (verwaltung != null) {
			int matrikelNummer = -1;
			Leistung[] leistungen = null;
			boolean anfrageOK;

			// Server abfragen: 1) Matrikelnummer zu Name
			anfrageOK = false;
			while(!anfrageOK) {
				try {
					matrikelNummer = verwaltung.martikelnummerZuName(name);
					anfrageOK=true;
					System.out.println("\nMartikelNummer: " + matrikelNummer);

					// Server abfragen: 2) Leistungen zur Matrikelnummer
					anfrageOK = false;
					leistungen = verwaltung.studienleistungZuMartikelnummer(matrikelNummer);
					anfrageOK=true;
					for (Leistung leistung : leistungen) {
						System.out.println("\nLeistung: " + leistung.getModul() + " - " + leistung.getNote());
					} 
				}
				catch (SOAPFaultException e) 
				{
					System.err.println("Anfrage gescheitert!");
					System.err.println(e);
					// Methode mit applikationsspezifischer, eigener Exception beenden
					throw new Exception("Anfrage gescheitert");
				}
				catch (HTTPException e) {
					System.err.println("Server nicht erreichbar! Anfrage wird erneut versendet");
					System.err.println(e);
					Thread.sleep(10000); // vor dem naechsten Versuch kurz warten 
				}
			}
		}
	}
}


SoapServer.java

package kap11_3.soapServer;

import jakarta.xml.ws.Endpoint;

public class SoapServer 
{
	public static void main(String[] args) 
	{
		// SOAP Service erstellen
		String url = "http://0.0.0.0:4434/verwaltung";
	    Endpoint.publish( url, new VerwaltungImpl() );
	    System.out.println("SOAP-Server gestartet: "+url);
	}
}

Speicher.java

package kap11_3.soapServer;

import soap.Student;
import soap.Leistung;

// Das ist eine Kopie der Klasse aus dem Package Studenten. 
// Der Server auf der Webseite hat eine andere Implementierung des Package im Package soap. 
// Deshalb können wir hier nicht die Klasse aus dem Package Studenten verwenden.  
public class Speicher {
	// Array, das die Studenten speichert
	// Kniff: Der Inhalt des Speichers existiert nur einmal, da static
	private static final Student[] studenten;

	// Kniff: Der Inhalt des Speichers wird durch diese Methode beim ersten Zugriff erzeugt
	static
	{
		// Datensaetze erzeugen
		studenten = Speicher.fuelleMitUnsinn(100);
	}

	// Methoden fuer den Zugriff auf die gespeicherten Daten
	public static Student[] getStudenten()
	{
		return studenten;
	}

	public static Student getSucheMatrikelNummerZuName(String name)
	{
		for(Student s : studenten)
		{
			if(s.getName().equals(name))
			{
				return s;
			}
		}
		return null;
	}

	public static Student getStudentenInfoZuMatrikelNummer(int matrikelNummer)
	{
		for(Student s : studenten)
		{
			if(s.getMatrikelNummer() == matrikelNummer)
			{
				return s;
			}
		}	
		return null;
	}	

	// Utility-Methoden
	public static Student[] fuelleMitUnsinn(int Zahl)
	{
		// Hilfsvariablen zum Erzeugen von Datensaetzen
		  final String [] vornamen = { "Mia","Ben","Emma","Jonas","Hannah","Leon","Sofia","Finn","Anna","Elias"};
		  final String [] nachnamen = {"Bauer","Becker","Fischer","Fuchs","Hartmann","Lang", "Jung","Hofmann","Huber"};
		  final String [] module = {"Analysis A","Lineare Algebra A","Analysis B","Lineare Algebra B","Numerik A",
				"Stochastik A","Stochastik B","Numerik partieller Differentialgleichungen 1","Numerik partieller Differentialgleichungen 2",
				"Baumechanik I (Statik starrer Koerper)","Baumechanik II (Elastomechanik)","Baumechanik III (Kinematik und Kinetik)",
				"Kontinuumsmechanik I","Modellbildung im Ingenieurwesen","Numerische Mechanik","Festkoerpermechanik","Finite Elemente II",
				"Grundlagen der Elektrotechnik","Umweltbiologie und -chemie","Stroemungsmechanik","Thermodynamik im Ueberblick",
				"Datenstrukturen, Algorithmen und Programmierung","Datenbanksysteme im Ingenieurwesen","Graphen und Netze","Baustoffkunde I",
				"Baustoffkunde II","Ausgleichungsrechnung und Statistik I","Ausgleichungsrechnung und Statistik II",
		"Projekte des Ingenieurwesens" };

		Student[] unsinn = new Student[Zahl];

		for(int i=0; i < Zahl; i++) {
			unsinn[i]=new Student();
			int vn_indx = (int)(Math.random()*vornamen.length);
			int nn_indx = (int)(Math.random()*nachnamen.length);
			unsinn[i].setName(vornamen[vn_indx] + " " + nachnamen[nn_indx]);
			unsinn[i].setMatrikelNummer(vn_indx * 100 + nn_indx + i * 10000);
			int notenZahl = (int)(Math.random()*8);
			if(notenZahl >= 1) {
				Leistung[] leistungen = new Leistung[notenZahl];
				for(int j=0; j < notenZahl; j++) {
					int mod_indx = (int)(Math.random()*module.length);
					leistungen[j] = new Leistung();
					leistungen[j].setModul(module[mod_indx]);
					leistungen[j].setNote((int)(Math.random()*5) + 1);
				}
				unsinn[i].setLeistungen(leistungen);
			}
			else
				unsinn[i].setLeistungen(null);
		}
		return unsinn;
	}

	public static boolean sindArraysGleich(Student[] a, Student[] b) {
		boolean istUnGleich = false;
		if(a.length == b.length)
		{
			for(int i=0; i < a.length; i++) {
				istUnGleich |= a[i].getMatrikelNummer() != b[i].getMatrikelNummer();
				istUnGleich |= !(a[i].getName().equals(b[i].getName()));
				if(a[i].getLeistungen() != null) {
					for(int j=0; j < a[i].getLeistungen().length; j++) {
						istUnGleich |= !(a[i].getLeistungen()[j].getModul().equals(b[i].getLeistungen()[j].getModul())) ;
						istUnGleich |= a[i].getLeistungen()[j].getNote() != b[i].getLeistungen()[j].getNote() ;
					}
				}
				if(istUnGleich)
					System.out.println("Ungleich a="+ a + "| b=" + b);
			}
		}
		else
			istUnGleich = true;

		return !istUnGleich;
	}
}

VerwaltungImpl.java

package kap11_3.soapServer;

import jakarta.jws.WebService;

import soap.Student;
import soap.Leistung;
import soap.VerwaltungInterface;


@WebService( endpointInterface="soap.VerwaltungInterface" )
public class VerwaltungImpl implements VerwaltungInterface 
{
	@Override
	public int martikelnummerZuName(String name) 
	{
		System.out.print("matrikelNummerZuName: "+ name);
		Student s = Speicher.getSucheMatrikelNummerZuName(name);
		
		if(s != null)
		{
			System.out.println(" "+ s.getMatrikelNummer());
			return s.getMatrikelNummer();
		}
		
		System.out.println(" nicht gefunden");
		return -1;
	}

	@Override
	public Leistung[] studienleistungZuMartikelnummer(int matrikelNummer) 
	{
		System.out.print("StudienleistungZuMartikelnummer: "+ matrikelNummer);
		
		Student s = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		
		if(s != null)
		{
			System.out.println(" "+ s.getName() + " mit " + s.getLeistungen().length + " Leistungen");
			return s.getLeistungen();
		}
		
		System.out.println(" nicht gefunden");
		return null;
	}

	@Override
	public Student nameZuMatrikelnummer(int matrikelNummer) {
		{
			System.out.print("nameZuMartikelnummer: "+ matrikelNummer);
			
			Student s = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
			
			if(s != null)
			{
				Student myStudent = new Student();
				
				myStudent.setMatrikelNummer(s.getMatrikelNummer());
				myStudent.setName(s.getName());
				myStudent.setLeistungen(null);
				
				System.out.println(" "+ s.getName());
				return myStudent;
			}
		
			System.out.println(" nicht gefunden");
			return null;
		}
	}

}




NichtGefundenException.java

package kap11_3.soapServerException;

import jakarta.xml.ws.WebServiceException;

public class NichtGefundenException extends WebServiceException {
	private static final long serialVersionUID = 1L;
	String fehlerMeldung;
	int fehlerCode;
	
	NichtGefundenException(String fehlerMeldung, int fehlerCode) {
		this.fehlerMeldung = fehlerMeldung;
		this.fehlerCode = fehlerCode;
	}
	
	@Override
	public String toString() {
		return "NichtGefunden: " + fehlerMeldung + " (" + fehlerCode + ")";
	}
}

SoapServerException.java

package kap11_3.soapServerException;

import jakarta.xml.ws.Endpoint;

public class SoapServerException 
{
	public static void main(String[] args) 
	{
		// SOAP Service erstellen
		String url = "http://localhost:4434/verwaltung";
	    Endpoint.publish( url, new VerwaltungImplException() );
	    System.out.println("SOAP-Server gestartet: "+url);
	}
}

VerwaltungImplException.java

package kap11_3.soapServerException;

import jakarta.jws.WebService;
import kap11_3.soapServer.Speicher;
import soap.Leistung;
import soap.Student;

@WebService( endpointInterface="soapServerException.VerwaltungInterfaceException" )
public class VerwaltungImplException implements VerwaltungInterfaceException
{
	@Override
	public int martikelnummerZuName(String name) throws NichtGefundenException 
	{
		System.out.print("matrikelNummerZuName: "+ name);
		Student s = Speicher.getSucheMatrikelNummerZuName(name);
		
		if(s != null)
		{
			System.out.println(" "+ s.getMatrikelNummer());
			return s.getMatrikelNummer();
		}
		System.out.println(" nicht gefunden");
		throw new NichtGefundenException("unbekannter Name", 1);
	}

	@Override
	public Leistung[] studienleistungZuMartikelnummer(int matrikelNummer) throws NichtGefundenException 
	{
		System.out.print("StudienleistungZuMartikelnummer: "+ matrikelNummer);
		
		Student s = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		
		if(s != null)
		{
			System.out.println(" "+ s.getName() + " mit " + s.getLeistungen().length + " Leistungen");
			return s.getLeistungen();
		}
			System.out.println(" nicht gefunden");
		throw new NichtGefundenException("ungueltige Matrikelnummer",2);
	}
}

VerwaltungInterfaceException.java

package kap11_3.soapServerException;

import jakarta.jws.*;

import soap.Leistung;

@WebService
public interface VerwaltungInterfaceException 
{
	public int martikelnummerZuName( @WebParam( name = "name" ) String name ) throws NichtGefundenException ;
	
	public Leistung[] studienleistungZuMartikelnummer( @WebParam( name = "matrikelNummer" ) int matrikelNummer ) throws NichtGefundenException ;
}

Vorschau der Java-Klassen zu Kapitel 11.6.1


RestServerApp.java

/*
 * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package kap11_5_1.restServer;

// Inspiriert durch https://github.com/eclipse-ee4j/jersey/tree/3.1.1/examples/helloworld-pure-jax-rs

import java.io.IOException;
import java.net.URI;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import jakarta.ws.rs.core.UriBuilder;

public class RestServerApp {

	public static URI getBaseURI() {
		return UriBuilder.fromUri(
					"http://localhost/") // "Wurzel des Service" 
					.port(4434) 		 // Port des Service
					.build();
	}

	static HttpServer startServer() throws IOException {

		// Einfachen Webserver erzeugen und mit Service verbinden
		final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
				getBaseURI(),
				new ResourceConfig(VerwaltungService.class),
				false
				);
		
		// Thread fuer Service erzeugen und eine Abbruchmoeglichkeit einbauen
		Runtime.getRuntime().addShutdownHook(
				new Thread(new Runnable() {
					@Override
					public void run() {
						server.shutdownNow();
					}
				}));

		// Webserver mit Service starten
		server.start();

		return server;
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		System.out.println("REST Server startet");

		startServer();

		System.out.println("Rest Server läuft unter " + getBaseURI());
		
		Thread.currentThread().join();
	}

}

VerwaltungService.java

/*
 * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package kap11_5_1.restServer;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

import studierende.Speicher;
import studierende.Student;

@Path("student")
public class VerwaltungService {

//    @GET
//    @Produces(MediaType.TEXT_PLAIN)
//    public String getHello() {
//        return "Hello World"; 
//    }
//    
//    @GET
//    @Path("hi")
//    @Produces(MediaType.TEXT_PLAIN)
//    public String getHi() {
//        return "Hi World"; 
//    }
    

	// Pfad 1 und Pfad 2 der Server-Sitemap fuehren auf diese Methode
	// diese verzweigt je nach Aufruf mit oder ohne Query-Parameter 
	@GET
	//@Path("/")
	@Produces(MediaType.APPLICATION_JSON) 
	public String getListeOderSuche(@QueryParam("name") String name) {
		System.out.print("getListeOderSuche: "+ name + " ");

		if(name == null)
			// Pfad 1: kein Parameter: gesamte Liste
			return getListeVonStudenten();
		else
			// Pfad 2: mit Parameter: nur ein Eintrag
			return getSucheMatrikelNummerZuName(name);
	}
    
	// Funktion fuer Pfad 1 der Server-Sitemap: Namen und Matrikelnummern aller Studenten
	public String getListeVonStudenten() 
	{
		String ergebnisAlsJSON;

		System.out.println("getListeVonStudenten");

		// GSON fuer Umwandlung in JSON
		Gson gson = new GsonBuilder().create();

		// Wir wollen nur einen Teil transportieren, deswegen muss Liste ueberarbeitet werden
		JsonArray nurMatrikelnummerUndName = new JsonArray();

		for(Student s : Speicher.getStudenten())
		{
			JsonObject dataset = new JsonObject();
			dataset.addProperty("matrikelNummer", s.matrikelNummer);
			dataset.addProperty("name", s.name);
			nurMatrikelnummerUndName.add(dataset);
		}
		ergebnisAlsJSON = gson.toJson(nurMatrikelnummerUndName);
		return ergebnisAlsJSON;
	}

	// Funktion fuer Pfad 2 der Server-Sitemap: Matrikelnummer zum Namen
	public String getSucheMatrikelNummerZuName(String name) 
	{
		Student myStudent = null;
		JsonObject matrikelnummer = null;
		String ergebnisAlsJSON;

		Gson gson = new GsonBuilder().create();

		System.out.print("getSucheMatrikelNummerZuName: "+ name);

		myStudent = Speicher.getSucheMatrikelNummerZuName(name);
		if(myStudent != null)
		{
			matrikelnummer = new JsonObject();
			matrikelnummer.addProperty("matrikelNummer", myStudent.matrikelNummer);
		}
		System.out.println(" "+ matrikelnummer);
		ergebnisAlsJSON = gson.toJson(matrikelnummer);
		return ergebnisAlsJSON;
	}

	
	// Funktion fuer Pfad 3 der Server-Sitemap: Name zu einer Matrikelnummer
	@GET
	@Path("/{matrikelNummer}")
	@Produces(MediaType.APPLICATION_JSON)
	public String getStudentenInfoZuMatrikelNummer(@PathParam("matrikelNummer") int matrikelNummer) 
	{
		Student myStudent = null;
		String ergebnisAlsJSON = "null";

		Gson gson = new GsonBuilder().create();

		System.out.print("getStudentenInfoZuMatrikelNummer: "+ matrikelNummer);

		myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		if(myStudent != null)
		{
			System.out.println(" "+ myStudent.name + " mit " + myStudent.leistungen.length + " Leistungen");

			// Wir wollen nur einen Teil transportieren, deswegen muss Liste ueberarbeitet werden
			JsonObject nurMatrikelnummerUndName = new JsonObject();
			nurMatrikelnummerUndName.addProperty("matrikelNummer", myStudent.matrikelNummer);
			nurMatrikelnummerUndName.addProperty("name", myStudent.name);
			ergebnisAlsJSON = gson.toJson(nurMatrikelnummerUndName);
		}
		else
			System.out.println(" nicht gefunden.");

		return ergebnisAlsJSON;
	}
    
	// Funktion fuer Pfad 4 der Server-Sitemap: Leistungen zu einer Matrikelnummer
	@GET
	@Path("/{matrikelNummer}/leistung")
	@Produces(MediaType.APPLICATION_JSON)
	public String getLeistungVonStudenten(@PathParam("matrikelNummer") int matrikelNummer) 
	{
		Student myStudent = null;
		String ergebnisAlsJSON = "null";

		Gson gson = new GsonBuilder().create();

		System.out.print("getLeistungVonStudenten: "+ matrikelNummer);

		myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		if(myStudent != null)
		{
			System.out.println(" "+ myStudent.name + " mit " + myStudent.leistungen.length + " Leistungen");
			ergebnisAlsJSON = gson.toJson(myStudent.leistungen);
		}
		else
			System.out.println(" nicht gefunden.");

		return ergebnisAlsJSON;
	}

}

Vorschau der Java-Klassen zu Kapitel 11.6.2.2 und 11.6.3


RestServerApp.java

/*
 * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package kap11_6_1.restServerHTTPErrors;

// Inspiriert durch https://github.com/eclipse-ee4j/jersey/tree/3.1.1/examples/helloworld-pure-jax-rs

import java.io.IOException;
import java.net.URI;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import jakarta.ws.rs.core.UriBuilder;

public class RestServerApp {

	public static URI getBaseURI() {
		return UriBuilder.fromUri(
					"http://localhost/") // "Wurzel des Service" 
					.port(4434) 		 // Port des Service
					.build();
	}

	static HttpServer startServer() throws IOException {

		// Einfachen Webserver erzeugen und mit Service verbinden
		final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
				getBaseURI(),
				new ResourceConfig(VerwaltungService.class),
				false
				);
		
		// Thread fuer Service erzeugen und eine Abbruchmoeglichkeit einbauen
		Runtime.getRuntime().addShutdownHook(
				new Thread(new Runnable() {
					@Override
					public void run() {
						server.shutdownNow();
					}
				}));

		// Webserver mit Service starten
		server.start();

		return server;
	}

	public static void main(String[] args) throws IOException, InterruptedException {
		System.out.println("REST Server startet");

		startServer();

		System.out.println("Rest Server läuft unter " + getBaseURI());
		
		Thread.currentThread().join();
	}

}

VerwaltungService.java

/*
 * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package kap11_6_1.restServerHTTPErrors;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.ResponseBuilder;

import studierende.Speicher;
import studierende.Student;

@Path("student")
public class VerwaltungService {

	// Pfad 1 und Pfad 2 der Server-Sitemap fuehren auf diese Methode
	// diese verzweigt je nach Aufruf mit oder ohne Query-Parameter 
	@GET
	//@Path("/")
	@Produces(MediaType.APPLICATION_JSON) 
	public Response getListeOderSuche(@QueryParam("name") String name) {
		System.out.print("getListeOderSuche: "+ name + " ");

		if(name == null)
			// Pfad 1: kein Parameter: gesamte Liste
			return getListeVonStudenten();
		else
			// Pfad 2: mit Parameter: nur ein Eintrag
			return getSucheMatrikelNummerZuName(name);
	}


	// Funktion fuer Pfad 1 der Server-Sitemap: Namen und Matrikelnummern aller Studenten
	public Response getListeVonStudenten() 
	{
		String ergebnisAlsJSON;
		ResponseBuilder responseBuilder;
		Response response;

		System.out.println("getListeVonStudenten");

		// GSON fuer Umwandlung in JSON
		Gson gson = new GsonBuilder().create();

		// Wir wollen nur einen Teil des Studentenarrays transportieren, deswegen muss Liste ueberarbeitet werden
		JsonArray nurMatrikelnummerUndName = new JsonArray();
		for(Student s : Speicher.getStudenten())
		{
			JsonObject dataset = new JsonObject();
			dataset.addProperty("matrikelNummer", s.matrikelNummer);
			dataset.addProperty("name", s.name);
			nurMatrikelnummerUndName.add(dataset);
		}
		ergebnisAlsJSON = gson.toJson(nurMatrikelnummerUndName);
		if (ergebnisAlsJSON==null) {
			// keine Daten gefunden ==> Fehlermeldung als HTTP-Status zurueckgeben
			// ResponseBuilder mit HTML Status 5xx instanziieren, Klartextnachricht anhaengen
			responseBuilder = Response.serverError();
			responseBuilder = responseBuilder.entity("500 Internal Server Error");
			// Response erzeugen
			response = responseBuilder.build();
			return response;
		} else {
			// Daten gefunden ==> HTTP-Status Erfolg und Daten in die Response
			responseBuilder = Response.ok(ergebnisAlsJSON, MediaType.APPLICATION_JSON);
			// Response erzeugen
			response = responseBuilder.build();
			return response;
		}
	}

	// Funktion fuer Pfad 2 der Server-Sitemap: Matrikelnummer zum Namen
	public Response getSucheMatrikelNummerZuName(String name) 
	{
		ResponseBuilder responseBuilder;
		Response response;
		Student myStudent = null;
		JsonObject matrikelnummer = null;
		String ergebnisAlsJSON;

		Gson gson = new GsonBuilder().create();

		System.out.print("getSucheMatrikelNummerZuName: "+ name);

		myStudent = Speicher.getSucheMatrikelNummerZuName(name);
		if(myStudent != null)
		{
			matrikelnummer = new JsonObject();
			matrikelnummer.addProperty("matrikelNummer", myStudent.matrikelNummer);
		}
		System.out.println(" "+ matrikelnummer);
		ergebnisAlsJSON = gson.toJson(matrikelnummer);
		if (matrikelnummer==null) {
			//JSON Fehlernachricht wird intanziiert
			ergebnisAlsJSON = gson.toJson("404 Not Found. The requested Name /"+name+" was not found on this server");
			//ResponseBuilder wird mit HTML Status 404 instanziiert
			responseBuilder = Response.status(Response.Status.NOT_FOUND);
			//Den ResponseBuilder wird zusaetzlich eine JSON Nachricht angehaengt
			responseBuilder = responseBuilder.entity(ergebnisAlsJSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;
		} else {
			//ResponseBuilder wird mit HTML Status 200 und einer Nachricht von Typ JSON instanziiert
			responseBuilder = Response.ok(ergebnisAlsJSON, MediaType.APPLICATION_JSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;
		}
	}

	// Funktion fuer Pfad 3 der Server-Sitemap: Name zu einer Matrikelnummer
	@GET
	@Path("/{matrikelNummer}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getStudentenInfoZuMatrikelNummer(@PathParam("matrikelNummer") int matrikelNummer) 
	{
		ResponseBuilder responseBuilder;
		Response response;
		Student myStudent = null;
		String ergebnisAlsJSON = "null";

		Gson gson = new GsonBuilder().create();

		System.out.print("getStudentenInfoZuMatrikelNummer: "+ matrikelNummer);

		myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		if(myStudent != null)
		{
			System.out.println(" "+ myStudent.name + " mit " + myStudent.leistungen.length + " Leistungen");

			// Wir wollen nur einen Teil transportieren, deswegen muss Liste ueberarbeitet werden
			JsonObject nurMatrikelnummerUndName = new JsonObject();
			nurMatrikelnummerUndName.addProperty("matrikelNummer", myStudent.matrikelNummer);
			nurMatrikelnummerUndName.addProperty("name", myStudent.name);
			ergebnisAlsJSON = gson.toJson(nurMatrikelnummerUndName);
			//ResponseBuilder wird mit HTML Status 200 und einer Nachricht von Typ JSON instanziiert
			responseBuilder = Response.ok(ergebnisAlsJSON, MediaType.APPLICATION_JSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;
		}
		else {
			System.out.println(" nicht gefunden.");
			ergebnisAlsJSON = gson.toJson("404 Not Found. The requested matrikelNummer /"+matrikelNummer+" was not found on this server");
			//ResponseBuilder wird mit HTML Status 404 instanziiert
			responseBuilder = Response.status(Response.Status.NOT_FOUND);
			//Den ResponseBuilder wird zusaetzlich eine JSON Nachricht angehaengt
			responseBuilder = responseBuilder.entity(ergebnisAlsJSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;

		}

	}

	// Funktion fuer Pfad 4 der Server-Sitemap: Leistungen zu einer Matrikelnummer
	@GET
	@Path("/{matrikelNummer}/leistung")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getLeistungVonStudenten(@PathParam("matrikelNummer") int matrikelNummer) 
	{
		ResponseBuilder responseBuilder;
		Response response;
		Student myStudent = null;
		String ergebnisAlsJSON = "null";

		Gson gson = new GsonBuilder().create();

		System.out.print("getLeistungVonStudenten: "+ matrikelNummer);

		myStudent = Speicher.getStudentenInfoZuMatrikelNummer(matrikelNummer);
		if(myStudent != null)
		{
			System.out.println(" "+ myStudent.name + " mit " + myStudent.leistungen.length + " Leistungen");
			ergebnisAlsJSON = gson.toJson(myStudent.leistungen);
			//ResponseBuilder wird mit HTML Status 200 und einer Nachricht von Typ JSON instanziiert
			responseBuilder = Response.ok(ergebnisAlsJSON, MediaType.APPLICATION_JSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;
		}
		else {
			System.out.println(" nicht gefunden.");
			ergebnisAlsJSON = gson.toJson("404 Not Found. The requested matrikelNummer /"+matrikelNummer+" was not found on this server");
			//ResponseBuilder wird mit HTML Status 404 instanziiert
			responseBuilder = Response.status(Response.Status.NOT_FOUND);
			//Den ResponseBuilder wird zusaetzlich eine JSON Nachricht angehaengt
			responseBuilder = responseBuilder.entity(ergebnisAlsJSON);
			//Response wird aus ResponseBuilder instanziiert. Response enthaelt den Statuscode und eine Nachricht, 
			//die jetzt als akzeptiertes Format zurueckgeliefert werden kann
			response = responseBuilder.build();
			return response;
		}
	}
}

RestClient.java

package kap11_6_2.restClient;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.MediaType;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import studierende.Leistung;
import studierende.Student;

public class RestClient {

	public static void main(String[] args) 
	{
		// URL des Servers
		String baseUrl   = "http://localhost:4434";
		// Name des Studenten, fuer den wir anfragen
		String name 		 = "Hannah Jung"; 

		// Relative Pfade auf dem Server
		String webContextPath = "/student";  
		String webContextUnderPath = "/leistung";
		
		Student student = new Student();
		student.matrikelNummer = -1;

		System.out.println( "\nAngefragte URL: " + baseUrl + webContextPath );

		// GSON Instanz fuer das Interpretieren der Antwort vom Server
		Gson gson = new GsonBuilder().create();
		
		// Jersey Client fuer das Abfragen des Servers erzeugen
		Client client = ClientBuilder.newClient();
		
		// Server abfragen: 1) Matrikelnummer zu Name
		// WebTarget erzeugen und richtigen Pfad angeben
		WebTarget target = client.target( baseUrl + webContextPath );
		// Parameter name anhaengen
		target = target.queryParam("name",name);
		// GET-Anfrage erzeugen
		Invocation invocation = target.request( MediaType.APPLICATION_JSON ).buildGet();
		// Anfrage an Server senden und JSON-String empfangen
		String jsonString = invocation.invoke(String.class );
		// JSON-String decodieren
		if(jsonString != null)
			student = gson.fromJson(jsonString, Student.class);
		
		if(student.matrikelNummer != -1)
		{
			System.out.println("\nStudent gefunden: " + student.matrikelNummer );
			
			// Server abfragen: 2) leistungen zur Matrikelnummer
			// WebTarget erzeugen und richtigen Pfad angeben
			target = client.target( baseUrl + webContextPath);
			// gefundene Matrikelnummer an Pfad anhaengen
			target = target.path( String.valueOf(student.matrikelNummer) );
			// Unterpfad /leistung an Pfad anhaengen
			target = target.path( webContextUnderPath );
			// GET-Anfrage erzeugen
			invocation = target.request( MediaType.APPLICATION_JSON ).buildGet();
			// Anfrag an Server senden und JSON-String empfangen
			jsonString = invocation.invoke(String.class );
			// JSON-String decodieren
			Leistung[] leistungen = gson.fromJson(jsonString, Leistung[].class);
			
			System.out.println("\nLeistungen:" );
			for(Leistung l : leistungen)
			{
				System.out.println(l.modul + ": " + l.note);	
			}
		}
		else
		{
			System.out.println("\nKeinen Studenten gefunden!" );
		}
	}
}

RestClientHTTP.java

package kap11_6_2.restClientHTTP;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import studierende.Leistung;
import studierende.Student;

public class RestClientHTTP {

	public static void main(String[] args) throws ClientProtocolException, IOException, URISyntaxException {

		// GSON Instanz fuer das Interpretieren der Antwort vom Server
		Gson gson = new GsonBuilder().create();

		// HTTP Client fuer das Senden von HTTP Requests
		CloseableHttpClient httpClient = HttpClients.createDefault();

		// URI aufbauen
		URIBuilder uriBuilder = new URIBuilder("http://localhost:4434/student/");
		uriBuilder.addParameter("name", "Mia Fischer");
		// GET Request auf Server
		HttpGet httpGet = new HttpGet(uriBuilder.build());
		CloseableHttpResponse response = httpClient.execute(httpGet);

		// Abholen der Antwort ueber einen StreamReader
		HttpEntity entity = response.getEntity();
		InputStreamReader httpStreamReader = new InputStreamReader(entity.getContent());

		// Parsen der Antwort mit GSON, Umwandeln in den von uns gewuenschten Typ
		Student student = new Student();
		student.matrikelNummer = -1;
		
		student = gson.fromJson(httpStreamReader, Student.class);

		// Aufraeumen 
		EntityUtils.consume(entity);
		response.close();

		if(student.matrikelNummer != -1)
		{
			// Student gefunden
			System.out.println("\nStudent gefunden: " + student.matrikelNummer);

			// URI aufbauen
			uriBuilder = new URIBuilder("http://localhost:4434/student/");
			uriBuilder = uriBuilder.setPath(uriBuilder.getPath() + Integer.toString(student.matrikelNummer));
			uriBuilder = uriBuilder.setPath(uriBuilder.getPath() + "/leistung");
			
			// GET Request auf unseren Server
			httpGet = new HttpGet(uriBuilder.build());
			response = httpClient.execute(httpGet);

			// Abholen der Antwort ueber einen StreamReader
			entity = response.getEntity();
			httpStreamReader = new InputStreamReader(entity.getContent());

			// Parsen der Antwort mit GSON, Umwandeln in den von uns gewuenschten Typ
			// JSON-String decodieren
			Leistung[] leistungen = gson.fromJson(httpStreamReader, Leistung[].class);

			// Aufraeumen 
			EntityUtils.consume(entity);
			response.close();

			System.out.println("\nLeistungen:" );
			for(Leistung l : leistungen)
			{
				System.out.println(l.modul + ": " + l.note);	
			}
		}
		else
		{
			System.out.println("\nKeinen Studenten gefunden!" );
		}
	}
}



RestClient.java

package kap11_6_2.restClientHTTPErrors;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.client.Invocation.Builder;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status.Family;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import studierende.Leistung;
import studierende.Student;

public class RestClient {

	public static void main(String[] args) 
	{
		// URL des Servers
		String baseUrl   = "http://localhost:4434";
		// Name des Studenten, fuer den wir anfragen
		String name 		 = "Hannah Jung"; 

		// Relative Pfade auf dem Server
		String webContextPath = "/student";  
		String webContextUnderPath = "/leistung";
		
		Student student = new Student();

		System.out.println( "\nAngefragte URL: " + baseUrl + webContextPath );

		// GSON Instanz fuer das Interpretieren der Antwort vom Server
		Gson gson = new GsonBuilder().create();
		
		// Jersey Client fuer das Abfragen des Servers erzeugen
		Client client = ClientBuilder.newClient();
		
		// Server abfragen: 1) Matrikelnummer zu Name
		// WebTarget erzeugen und richtigen Pfad angeben
		WebTarget target = client.target( baseUrl + webContextPath );
		// Parameter name anhaengen
		target = target.queryParam("name",name);
		// GET-Anfrage erzeugen
		Builder builder = target.request( MediaType.APPLICATION_JSON );
		Invocation invocation = builder.buildGet();
		// Anfrage an Server senden und JSON-String empfangen
		Response response = invocation.invoke(Response.class );
		// JSON-String decodieren
		String jsonString = response.readEntity(String.class);
		student = gson.fromJson(jsonString, Student.class);
		
		//Status pruefen der GET Anfrage
		if(response.getStatusInfo().getFamily() == Family.SUCCESSFUL)
		{
			System.out.println("\nStudent gefunden: " + student.matrikelNummer );
			
			// Server abfragen: 2) leistungen zur Matrikelnummer
			// WebTarget erzeugen und richtigen Pfad angeben
			target = client.target( baseUrl + webContextPath);
			// gefundene Matrikelnummer an Pfad anhaengen
			target = target.path( String.valueOf(student.matrikelNummer) );
			// Unterpfad /leistung an Pfad anhaengen
			target = target.path( webContextUnderPath );
			// GET-Anfrage erzeugen
			builder = target.request( MediaType.APPLICATION_JSON );
			invocation = builder.buildGet();
			// Anfrag an Server senden und JSON-String empfangen
			response = invocation.invoke(Response.class );
			// JSON-String decodieren
			jsonString = response.readEntity(String.class);
			Leistung[] leistungen = gson.fromJson(jsonString, Leistung[].class);
			
			System.out.println("\nLeistungen:" );
			for(Leistung l : leistungen)
			{
				System.out.println(l.modul + ": " + l.note);	
			}
		}
		else
		{
			System.out.println("\nKeinen Studenten gefunden!" );
		}
	}
}