Route Patterns
Routenmuster werden verwendet, um zu definieren, wie URLs bestimmten Ansichten zugeordnet werden, einschließlich dynamischer und optionaler Segmente, regulärer Ausdrücke und Wildcards. Routenmuster ermöglichen es dem Framework, URLs abzugleichen, Parameter zu extrahieren und URLs dynamisch zu generieren. Sie spielen eine entscheidende Rolle bei der Strukturierung der Navigation und der Komponentendarstellung einer App basierend auf dem Standort des Browsers.
Syntax der Routenmuster
Routenmuster in webforJ sind äußerst flexibel und unterstützen die folgenden Funktionen:
- Benannte Parameter: Gekennzeichnet durch
:paramName
, sind sie erforderlich, es sei denn, sie sind als optional gekennzeichnet. - Optionale Parameter: Gekennzeichnet durch
:paramName?
, können sie in der URL weggelassen werden. - Wildcards: Dargestellt durch
*
, erfassen sie alle verbleibenden Segmente der URL. - Einschränkungen für reguläre Ausdrücke: Einschränkungen können nur für benannte Parameter hinzugefügt werden (zum Beispiel
:id<[0-9]+>
).
Beispiel für Routenmusterdefinitionen
@Route("customer/:id<[0-9]+>/named/:name/*")
public class CustomerView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
int id = parameters.getInt("id").orElse(0);
String name = parameters.getAlpha("name").orElse("Unbekannt");
String extra = parameters.getAlpha("*").orElse("");
String result =
"Kunden-ID: " + id + "-" +
"Name: " + name + "-" +
"*: " + extra;
console().log(result);
}
}
In diesem Beispiel:
:id<[0-9]+>
erfasst eine numerische Kunden-ID.:name
erfasst einen Namen.*
erfasst zusätzliche Pfadsegmente übernamed/:name
hinaus.
Benannte Parameter
Benannte Parameter werden definiert, indem einem Doppelpunkt :
der Parametername im Muster vorangestellt wird. Sie sind erforderlich, es sei denn, sie sind als optional gekennzeichnet. Benannte Parameter können auch reguläre Ausdrucks-Einschränkungen haben, um die Werte zu validieren.
Beispiel:
@Route("product/:id")
public class ProductView extends Composite<Div> {
// Komponentenlogik hier
}
Dieses Muster entspricht URLs wie /product/123
, wobei id
123
ist.
Optionale Parameter
Optionale Parameter werden angezeigt, indem ein ?
nach dem Parameternamen hinzugefügt wird. Diese Segmente sind nicht erforderlich und können in der URL weggelassen werden.
Beispiel:
@Route("order/:id?<[0-9]+>")
public class OrderView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
parameters.getInt("id").ifPresentOrElse(
id -> console().log("Bestell-ID: " + id),
() -> console().log("Keine Bestell-ID wurde angegeben")
);
}
}
Dieses Muster entspricht sowohl /order/123
, um einen numerischen Wert einzuschließen, als auch /order
, wodurch das Weglassen eines numerischen Wertes beim Eingeben von /order
ermöglicht wird.
Einschränkungen für reguläre Ausdrücke
Sie können reguläre Ausdruckseinschränkungen auf Parameter anwenden, indem Sie sie in spitze Klammern <>
einfügen. Dies ermöglicht es Ihnen, strengere Übereinstimmungsregeln für Parameter festzulegen.
Beispiel:
@Route("product/:code<[A-Z]{3}-[0-9]{4}>")
public class ProductView extends Composite<FlexLayout> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
parameters.get("code").ifPresentOrElse(
code -> console().log("Produktcode: " + code),
() -> console().error("Produktcode nicht gefunden"));
}
}
Dieses Muster entspricht nur Produktcodes im Format ABC-1234
. Zum Beispiel wird /product/XYZ-5678
übereinstimmen, aber /product/abc-5678
nicht.
Wildcard-Segmente
Wildcards können verwendet werden, um gesamte Pfade zu erfassen, die einem bestimmten Routensegment folgen, dürfen jedoch nur als letztes Segment im Muster erscheinen und erfassen alle nachfolgenden Werte in der URL. Für eine bessere Lesbarkeit können Wildcard-Segmente benannt werden. Anders als benannte Parameter können Wildcard-Segmente jedoch keine Einschränkungen haben.
Beispiel:
@Route("files/:pathname*")
public class FileManagerView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
parameters.get("pathname").ifPresentOrElse(
pathname -> console().log("FileManagerView: " + pathname),
() -> console().log("FileManagerView: Kein pathname-Parameter")
);
}
}
Dieses Muster entspricht jeder URL, die mit /files
beginnt und den Rest des Pfades als Wildcard erfasst.
Routenpriorität
Wenn mehrere Routen mit einer bestimmten URL übereinstimmen, bestimmt das Prioritätsattribut einer Route, welche Route zuerst ausgewählt wird. Dies ist besonders nützlich, wenn zwei oder mehr Routen in ihren Pfadmuster überlappen und Sie eine Möglichkeit benötigen, zu steuern, welche Vorrang hat. Das Prioritätsattribut ist sowohl in den Anmerkungen @Route
als auch @RouteAlias
verfügbar.
Wie das Prioritätssystem funktioniert
Das Prioritätsattribut ermöglicht es dem Router zu bestimmen, in welcher Reihenfolge Routen bewertet werden, wenn mehrere Routen mit einer bestimmten URL übereinstimmen könnten. Routen werden basierend auf ihren Prioritätswerten sortiert, wobei höhere Priorität (niedrigere numerische Werte) zuerst übereinstimmt. Dies stellt sicher, dass spezifischere Routen Vorrang vor allgemeineren haben.
Wenn zwei Routen die gleiche Priorität haben, löst der Router den Konflikt, indem er die Route auswählt, die zuerst registriert wurde. Dieser Mechanismus sorgt dafür, dass die korrekte Route ausgewählt wird, selbst wenn mehrere Routen in ihren URL-Mustern überlappen.
Standardmäßig haben alle Routen eine Priorität von 10
.
Beispiel: Konfliktierende Routen
Betrachten Sie ein Szenario, in dem zwei Routen ähnliche URL-Muster entsprechen:
@Route(value = "products/:category", priority = 9)
public class ProductCategoryView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
String category = parameters.get("category").orElse("unbekannt");
console().log("Kategorie anzeigen: " + category);
}
}
@Route(value = "products/:category/:productId?<[0-9]+>")
public class ProductView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
String productId = parameters.get("productId").orElse("unbekannt");
console().log("Produkt anzeigen: " + productId);
}
}
Hier ist, wie das Prioritätssystem bei der Auflösung von Konflikten hilft:
ProductCategoryView
entspricht URLs wie/products/electronics
.ProductView
entspricht spezifischeren URLs wie/products/electronics/123
, wobei123
die Produkt-ID ist.
In diesem Fall könnten beide Routen der URL /products/electronics
entsprechen. Da jedoch ProductCategoryView
eine höhere Priorität hat (Priorität = 9), wird sie zuerst abgeglichen, wenn keine productId
in der URL vorhanden ist. Für URLs wie /products/electronics/123
wird ProductView
aufgrund der Anwesenheit des productId
-Parameters abgeglichen.