Erste Schritte mit HTTP-Anforderungen von Relay-Hybridverbindungen in Java
In diesem Schnellstart erstellen Sie Sender- und Empfängeranwendungen in Java, die mithilfe des HTTP-Protokolls Nachrichten senden und empfangen. Die Anwendungen verwenden das Hybrid Connections-Feature von Azure Relay. Allgemeine Informationen zu Azure Relay finden Sie unter Was ist Azure Relay?.
Diese Schnellstartanleitung umfasst folgende Schritte:
- Erstellen eines Relay-Namespace über das Azure-Portal
- Erstellen einer Hybridverbindung in diesem Namespace über das Azure-Portal
- Erstellen einer Serverkonsolenanwendung (Listener) zum Empfangen von Nachrichten
- Erstellen einer Clientkonsolenanwendung (Absender) zum Senden von Nachrichten
- Ausführen von Anwendungen
Voraussetzungen
- Java. Stellen Sie sicher, dass Sie JDK 1.8 oder höher ausführen.
- Maven. Stellen Sie sicher, dass Maven installiert ist.
- Azure Relay SDK Überprüfen des Java SDK
- Ein Azure-Abonnement. Falls Sie kein Abonnement besitzen, können Sie ein kostenloses Konto erstellen, bevor Sie beginnen.
Erstellen eines Namespace mithilfe des Azure-Portals
Melden Sie sich beim Azure-Portal an.
Wählen Sie im Menü links Alle Dienste aus. Wählen Sie Integration aus, suchen Sie nach Relays, zeigen Sie mit der Maus auf Relays, und wählen Sie dann Erstellen.
Führen Sie die folgenden Schritte auf der Seite Namespace erstellen aus:
Wählen Sie ein Azure-Abonnement aus, in dem der Namespace erstellt werden soll.
Wählen Sie unter Ressourcengruppe eine vorhandene Ressourcengruppe aus, in der der Namespace platziert werden soll, oder erstellen Sie eine neue Ressourcengruppe.
Geben Sie einen Namen für den Relay-Namespace ein.
Wählen Sie die Region aus, in dem bzw. in der Ihr Namespace gehostet werden soll.
Wählen Sie am unteren Rand der Seite die Option Bewerten + erstellen aus.
Wählen Sie auf der Seite Überprüfen + erstellen die Option Erstellen aus.
Nach ein paar Minuten sehen Sie die Seite Vermittlung für den Namespace.
Abrufen von Anmeldeinformationen für die Verwaltung
Wählen Sie auf der Seite Vermittlung die Option Freigegebene Zugriffsrichtlinien im linken Menü aus.
Wählen Sie auf der Seite Freigegebene Zugriffsrichtlinien die Option RootManageSharedAccessKey aus.
Klicken Sie unter SAS-Richtlinie: RootManageSharedAccessKey neben Primäre Verbindungszeichenfolge auf die Schaltfläche Kopieren. Dadurch wird die Verbindungszeichenfolge zur späteren Verwendung in die Zwischenablage kopiert. Fügen Sie diesen Wert in den Editor oder an einem anderen temporären Speicherort ein.
Wiederholen Sie den vorherigen Schritt, um den Wert von Primärschlüssel zu kopieren und zur späteren Verwendung an einem temporären Speicherort einzufügen.
Erstellen einer Hybridverbindung mit dem Azure-Portal
Führen Sie auf der Seite Relay für Ihren Namespace die folgenden Schritte aus, um eine Hybridverbindung zu erstellen.
Wählen Sie im linken Menü unter Entitäten die Option Hybridverbindungen und dann + Hybridverbindung aus.
Geben Sie auf der Seite Hybridverbindung erstellen einen Namen für die Hybridverbindung ein, und wählen Sie dann Erstellen aus.
Erstellen einer Serveranwendung (Listener)
Schreiben Sie eine Java-Konsolenanwendung, um auf Nachrichten von Relay zu lauschen und sie zu empfangen.
Erstellen einer Java-Anwendung
Wenn Sie die Option „Clientautorisierung erforderlich“ bei der Relay-Erstellung deaktiviert haben, können Sie mit jedem Browser Anforderungen an die URL der Hybridverbindungen senden. Für den Zugriff auf geschützte Endpunkte müssen Sie ein Token im ServiceBusAuthorization
-Header, der hier gezeigt wird, erstellen und übergeben.
Im Folgenden finden Sie Beispiele für eine einfache Maven-Projektstruktur und eine Java-Klasse, die das Senden von Anforderungen an eine Hybridverbindungs-URL mit Clientautorisierung mithilfe der Azure Relay-Bibliothek veranschaulichen.
Hinzufügen des Relay-Pakets
Ändern Sie die Datei „pom.xml“ in Ihrem Maven-Anwendungspaket so, dass das Azure Relay-Paket enthalten ist.
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-relay</artifactId>
<version>0.0.6</version>
</dependency>
Führen Sie mvn dependency:copy-dependencies -DoutputDirectory=lib
in Ihrem mvn-Projekt aus, um die JAR-Abhängigkeitsdatei im Verzeichnis „lib“ Ihres Projekts hinzuzufügen. Mit ihm werden alle Abhängigkeiten des mvn-Pakets azure-relay
importiert. Dieses Paket bietet Funktionen zum Erstellen von Relay-URIs (Uniform Resource Identifier) und -Token.
Schreiben von Code zum Senden von Nachrichten
Fügen Sie die JAR-Abhängigkeitsdateien dem ClassPath Ihrer Datei
Listener.java
hinzu.javac -cp lib/* src/main/java/com/example/listener/Listener.Java
Importieren Sie die Abhängigkeiten in Ihre
Listener.java
-Klasse.import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.util.Scanner; import com.microsoft.azure.relay.HybridConnectionListener; import com.microsoft.azure.relay.RelayConnectionStringBuilder; import com.microsoft.azure.relay.RelayedHttpListenerResponse; import com.microsoft.azure.relay.TokenProvider;
Fügen Sie folgende
constants
am Anfang der DateiListener.java
einer Java-createConnectionString
-Funktion hinzu, um Details zur Hybridverbindung anzugeben.public static String createConnectionString(){ StringBuilder connectionString = new StringBuilder(); connectionString.append("Endpoint=sb://"); connectionString.append("{namespace}"); connectionString.append(".servicebus.windows.net/;SharedAccessKeyName="); connectionString.append("{keyrule}"); connectionString.append(";SharedAccessKey="); connectionString.append("{key}"); connectionString.append(";EntityPath="); connectionString.append("{path}"); return connectionString.toString(); }
Ersetzen Sie die Platzhalter in Klammern durch die Werte, die beim Erstellen der Hybridverbindung abgerufen wurden.
namespace
– der Relay-Namespace. Achten Sie darauf, dass Sie den vollqualifizierten Namespacenamen verwenden, wie z.B.{namespace}.servicebus.windows.net
.path
– der Name der Hybridverbindungkeyrule
– Name des Schlüssels für SAS-Richtlinien, der standardmäßigRootManageSharedAccessKey
ist.nst key
– Der Primärschlüssel des zuvor gespeicherten Namespaces.
Fügen Sie der Datei
Listener.java
den folgenden Code hinzu. Die Hauptfunktion sollte wie der folgende Code aussehen:public static void main( String[] args ) throws URISyntaxException { String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString(); RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME); TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider( connectionParams.getSharedAccessKeyName(), connectionParams.getSharedAccessKey()); HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider); // The "context" object encapsulates both the incoming request and the outgoing response listener.setRequestHandler((context) -> { String receivedText = ""; if (context.getRequest().getInputStream() != null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) { StringBuilder builder = new StringBuilder(); String inputLine; while ((inputLine = reader.readLine()) != null) { builder.append(inputLine); } receivedText = builder.toString(); } catch (IOException e) { System.out.println(e.getMessage()); } } System.out.println("requestHandler received " + receivedText); RelayedHttpListenerResponse response = context.getResponse(); response.setStatusCode(202); response.setStatusDescription("OK"); try { response.getOutputStream().write(("Echo: " + receivedText).getBytes()); } catch (IOException e) { e.printStackTrace(); } // The context MUST be closed for the message to be sent response.close(); }); listener.openAsync().join(); Scanner in = new Scanner(System.in); System.out.println("Press ENTER to terminate this program."); in.nextLine(); listener.close(); in.close(); }
Die Datei
Listener.java
sollte wie folgt aussehen:package com.example.listener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.util.Scanner; import com.microsoft.azure.relay.HybridConnectionListener; import com.microsoft.azure.relay.RelayConnectionStringBuilder; import com.microsoft.azure.relay.RelayedHttpListenerResponse; import com.microsoft.azure.relay.TokenProvider; public class Listener { public static String createConnectionString(){ StringBuilder connectionString = new StringBuilder(); connectionString.append("Endpoint=sb://"); connectionString.append("{namespace}"); connectionString.append(".servicebus.windows.net/;SharedAccessKeyName="); connectionString.append("{keyrule}"); connectionString.append(";SharedAccessKey="); connectionString.append("{key}"); connectionString.append(";EntityPath="); connectionString.append("{path}"); return connectionString.toString(); } public static void main( String[] args ) throws URISyntaxException { String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString(); RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME); TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider( connectionParams.getSharedAccessKeyName(), connectionParams.getSharedAccessKey()); HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider); // The "context" object encapsulates both the incoming request and the outgoing response listener.setRequestHandler((context) -> { String receivedText = ""; if (context.getRequest().getInputStream() != null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) { StringBuilder builder = new StringBuilder(); String inputLine; while ((inputLine = reader.readLine()) != null) { builder.append(inputLine); } receivedText = builder.toString(); } catch (IOException e) { System.out.println(e.getMessage()); } } System.out.println("requestHandler received " + receivedText); RelayedHttpListenerResponse response = context.getResponse(); response.setStatusCode(202); response.setStatusDescription("OK"); try { response.getOutputStream().write(("Echo: " + receivedText).getBytes()); } catch (IOException e) { e.printStackTrace(); } // The context MUST be closed for the message to be sent response.close(); }); listener.openAsync().join(); Scanner in = new Scanner(System.in); System.out.println("Press ENTER to terminate this program."); in.nextLine(); listener.close(); in.close(); } }
Erstellen einer Clientanwendung (Absender)
Sie können einen beliebigen HTTP-Client verwenden oder eine Java-Konsolenanwendung schreiben, um Nachrichten an Relay zu senden.
Erstellen einer Java-Anwendung
Wenn Sie die Option „Clientautorisierung erforderlich“ bei der Relay-Erstellung deaktiviert haben, können Sie mit jedem Browser Anforderungen an die URL der Hybridverbindungen senden. Für den Zugriff auf geschützte Endpunkte müssen Sie ein Token im ServiceBusAuthorization
-Header, der hier gezeigt wird, erstellen und übergeben.
Im Folgenden finden Sie Beispiele für eine einfache Maven-Projektstruktur und eine Java-Klasse, die das Senden von Anforderungen an eine Hybridverbindungs-URL mit Clientautorisierung mithilfe der Azure Relay-Bibliothek veranschaulichen.
Hinzufügen des Relay-Pakets
Ändern Sie die Datei „pom.xml“ in Ihrem Maven-Anwendungspaket so, dass das Azure Relay-Paket enthalten ist.
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-relay</artifactId>
<version>0.0.6</version>
</dependency>
Führen Sie mvn dependency:copy-dependencies -DoutputDirectory=lib
in Ihrem mvn-Projekt aus, um die JAR-Abhängigkeitsdatei im Verzeichnis „lib“ Ihres Projekts hinzuzufügen. Mit ihm werden auch alle Abhängigkeiten des mvn-Pakets azure-relay
importiert. Dieses Paket bietet Funktionen zum Erstellen von Relay-URIs (Uniform Resource Identifier) und -Token.
Schreiben von Code zum Senden von Nachrichten
Fügen Sie die JAR-Abhängigkeitsdateien dem ClassPath Ihrer Datei
Sender.java
hinzu.javac -cp lib/* src/main/java/com/example/sender/Sender.Java
Importieren Sie die Abhängigkeiten in Ihre
Sender.java
-Klasse.import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import java.util.Scanner; import com.microsoft.azure.relay.RelayConnectionStringBuilder; import com.microsoft.azure.relay.TokenProvider;
Fügen Sie folgende
constants
am Anfang der DateiSender.java
einer Java-createConnectionString
-Funktion hinzu, um Details zur Hybridverbindung anzugeben.public static String createConnectionString(){ StringBuilder connectionString = new StringBuilder(); connectionString.append("Endpoint=sb://"); connectionString.append("{namespace}"); connectionString.append(".servicebus.windows.net/;SharedAccessKeyName="); connectionString.append("{keyrule}"); connectionString.append(";SharedAccessKey="); connectionString.append("{key}"); connectionString.append(";EntityPath="); connectionString.append("{path}"); return connectionString.toString(); }
Ersetzen Sie die Platzhalter in Klammern durch die Werte, die beim Erstellen der Hybridverbindung abgerufen wurden.
namespace
– der Relay-Namespace. Achten Sie darauf, dass Sie den vollqualifizierten Namespacenamen verwenden, wie z.B.{namespace}.servicebus.windows.net
.path
– der Name der Hybridverbindungkeyrule
– Name des Schlüssels für SAS-Richtlinien, der standardmäßigRootManageSharedAccessKey
ist.nst key
– Der Primärschlüssel des zuvor gespeicherten Namespaces.
Fügen Sie der Datei
Sender.java
den folgenden Code hinzu. Die Hauptfunktion sollte wie der folgende Code aussehen.public static void main(String[] args) throws IOException { String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString(); if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){ System.err.println("Connection string is null or empty. Please check your createConnectionString method."); return; } RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME); TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider( connectionParams.getSharedAccessKeyName(), connectionParams.getSharedAccessKey()); URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath()); String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken(); Scanner in = new Scanner(System.in); while (true) { System.out.println("Press ENTER to terminate this program."); String message = in.nextLine(); int value = System.in.read(); if (value == '\n' || value == '\r') { System.out.println("Terminating the program..."); break;} // Starting a HTTP connection to the listener HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Sending an HTTP request to the listener // To send a message body, use POST conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST"); conn.setRequestProperty("ServiceBusAuthorization", tokenString); conn.setDoOutput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); out.write(message, 0, message.length()); out.flush(); out.close(); // Reading the HTTP response String inputLine; BufferedReader reader = null; StringBuilder responseBuilder = new StringBuilder(); try { InputStream inputStream = conn.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); System.out.println("status code: " + conn.getResponseCode()); while ((inputLine = reader.readLine()) != null) { responseBuilder.append(inputLine); } System.out.println("received back " + responseBuilder.toString()); } catch (IOException e) { System.out.println("The listener is offline or could not be reached."); break; } finally { if (reader != null) { reader.close(); } } } in.close(); } static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException { StringBuilder urlBuilder = new StringBuilder(endpoint + entity); // For HTTP connections, the scheme must be https:// int schemeIndex = urlBuilder.indexOf("://"); if (schemeIndex < 0) { throw new IllegalArgumentException("Invalid scheme from the given endpoint."); } urlBuilder.replace(0, schemeIndex, "https"); return new URL(urlBuilder.toString()); }
Die Datei
Sender.java
sollte wie folgt aussehen:package com.example.sender; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.time.Duration; import java.util.Scanner; import com.microsoft.azure.relay.RelayConnectionStringBuilder; import com.microsoft.azure.relay.TokenProvider; public class Sender { public static String createConnectionString(){ StringBuilder connectionString = new StringBuilder(); connectionString.append("Endpoint=sb://"); connectionString.append("{namespace}"); connectionString.append(".servicebus.windows.net/;SharedAccessKeyName="); connectionString.append("{keyrule}"); connectionString.append(";SharedAccessKey="); connectionString.append("{key}"); connectionString.append(";EntityPath="); connectionString.append("{path}"); return connectionString.toString(); } public static void main(String[] args) throws IOException { String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString(); if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){ System.err.println("Connection string is null or empty. Please check your createConnectionString method."); return; } RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME); TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider( connectionParams.getSharedAccessKeyName(), connectionParams.getSharedAccessKey()); URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath()); String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken(); Scanner in = new Scanner(System.in); while (true) { System.out.println("Press ENTER to terminate this program."); String message = in.nextLine(); int value = System.in.read(); if (value == '\n' || value == '\r') { System.out.println("Terminating the program..."); break;} // Starting a HTTP connection to the listener HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Sending an HTTP request to the listener // To send a message body, use POST conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST"); conn.setRequestProperty("ServiceBusAuthorization", tokenString); conn.setDoOutput(true); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); out.write(message, 0, message.length()); out.flush(); out.close(); // Reading the HTTP response String inputLine; BufferedReader reader = null; StringBuilder responseBuilder = new StringBuilder(); try { InputStream inputStream = conn.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); System.out.println("status code: " + conn.getResponseCode()); while ((inputLine = reader.readLine()) != null) { responseBuilder.append(inputLine); } System.out.println("received back " + responseBuilder.toString()); } catch (IOException e) { System.out.println("The listener is offline or could not be reached."); break; } finally { if (reader != null) { reader.close(); } } } in.close(); } static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException { StringBuilder urlBuilder = new StringBuilder(endpoint + entity); // For HTTP connections, the scheme must be https:// int schemeIndex = urlBuilder.indexOf("://"); if (schemeIndex < 0) { throw new IllegalArgumentException("Invalid scheme from the given endpoint."); } urlBuilder.replace(0, schemeIndex, "https"); return new URL(urlBuilder.toString()); } }
Hinweis
Der Beispielcode in diesem Artikel verwendet eine Verbindungszeichenfolge, um sich bei einem Azure Relay-Namespace zu authentifizieren, um das Lernprogramm einfach zu halten. Es wird empfohlen, die Microsoft Entra ID-Authentifizierung in Produktionsumgebungen zu verwenden, anstatt Verbindungszeichenfolgen oder freigegebene Zugriffssignaturen zu verwenden, die einfacher kompromittiert werden können. Ausführliche Informationen und Beispielcode für die Verwendung der Microsoft Entra ID-Authentifizierung finden Sie unter Authentifizieren und Autorisieren einer Anwendung mit Microsoft Entra ID für den Zugriff auf Azure Relay-Entitäten und Authentifizieren einer verwalteten Identität mit Microsoft Entra-ID für den Zugriff auf Azure Relay-Ressourcen.
Ausführen der Anwendungen
- Führen Sie die Serveranwendung über eine Java-Eingabeaufforderung oder den Anwendungstyp
java -cp <jar_dependency_path> com.example.listener.Listener.java
aus. - Führen Sie die Clientanwendung über eine Java-Eingabeaufforderung oder den Anwendungstyp
java -cp <jar_dependency_path> com.example.sender.Sender.java
aus, und geben Sie Text ein. - Stellen Sie sicher, dass von der Konsole der Serveranwendung der Text ausgegeben wird, der in die Clientanwendung eingegeben wurde.
Glückwunsch! Sie haben mithilfe von Java eine Anwendung für End-to-End-Hybridverbindungen erstellt.
Nächste Schritte
In diesem Schnellstart haben Sie Client- und Serveranwendungen in Java erstellt, die mithilfe von HTTP Nachrichten senden und empfangen. Das Hybrid Connections-Feature von Azure Relay unterstützt auch die Verwendung von WebSockets zum Senden und Empfangen von Nachrichten. Informationen zur Verwendung von WebSockets mit Hybrid Connections von Azure Relay finden Sie unter Erste Schritte mit WebSockets von Relay Hybrid Connections in Node.
In diesem Schnellstart haben Sie Java zum Erstellen von Client- und Serveranwendungen verwendet. Informationen zum Schreiben von Client- und Serveranwendungen mithilfe von .NET Framework finden Sie unter Erste Schritte mit WebSockets von Relay Hybrid Connections in .NET oder Erste Schritte mit WebSockets von Relay Hybrid Connections in Node.