Anleitung zu Spring Handler Mappings

1. Einleitung

In Spring MVC fungiert das DispatcherServlet als Front-Controller. Es empfängt alle eingehenden HTTP-Anforderungen und verarbeitet sie.

Einfach ausgedrückt erfolgt die Verarbeitung, indem die Anforderungen mithilfe von Handler-Zuordnungen an die entsprechende Komponente übergeben werden .

HandlerMapping ist eine Schnittstelle, die eine Zuordnung zwischen Anforderungen und Handlerobjekten definiert. Während das Spring MVC-Framework einige vorgefertigte Implementierungen bereitstellt, kann die Schnittstelle von Entwicklern implementiert werden, um eine angepasste Zuordnungsstrategie bereitzustellen.

In diesem Artikel werden einige der von Spring MVC bereitgestellten Implementierungen erläutert , nämlich BeanNameUrlHandlerMapping , SimpleUrlHandlerMapping , ControllerClassNameHandlerMapping , ihre Konfiguration und die Unterschiede zwischen ihnen.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping ist die Standardimplementierung von HandlerMapping . BeanNameUrlHandlerMapping ordnet Anforderungs-URLs Beans mit demselben Namen zu.

Diese spezielle Zuordnung unterstützt den direkten Namensabgleich sowie den Musterabgleich mit dem Muster "*".

Beispielsweise wird eine eingehende URL "/ foo" einer Bean namens "/ foo" zugeordnet . Ein Beispiel für die Musterzuordnung ist die Zuordnung von Anforderungen zu "/ foo *" zu Beans mit Namen, die mit "/ foo" beginnen, wie "/ foo2 /" oder "/ fooOne /" .

Lassen Sie uns dieses Beispiel hier konfigurieren und einen Bean-Controller registrieren, der Anforderungen an "/ beanNameUrl" verarbeitet :

@Configuration public class BeanNameUrlHandlerMappingConfig { @Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() { return new BeanNameUrlHandlerMapping(); } @Bean("/beanNameUrl") public WelcomeController welcome() { return new WelcomeController(); } }

Dies ist das XML-Äquivalent der obigen Java-basierten Konfiguration:

Es ist wichtig zu beachten, dass in beiden Konfigurationen das Definieren einer Bean für BeanNameUrlHandlerMapping nicht erforderlich ist, da es von Spring MVC bereitgestellt wird. Das Entfernen dieser Bean-Definition verursacht keine Probleme und Anforderungen werden weiterhin den registrierten Handler-Beans zugeordnet.

Nun werden alle Anfragen an „/ beanNameUrl“ wird weitergeleitet DispatcherServlet auf „ WelcomeController „. WelcomeController gibt einen Ansichtsnamen mit dem Namen " welcome " zurück.

Der folgende Code testet diese Konfiguration und stellt sicher, dass der richtige Ansichtsname zurückgegeben wird:

public class BeanNameMappingConfigTest { // ... @Test public void whenBeanNameMapping_thenMappedOK() { mockMvc.perform(get("/beanNameUrl")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

3. SimpleUrlHandlerMapping

Als nächstes ist SimpleUrlHandlerMapping die flexibelste HandlerMapping- Implementierung. Es ermöglicht eine direkte und deklarative Zuordnung zwischen Bean-Instanzen und URLs oder zwischen Bean-Namen und URLs.

Ordnen wir die Anforderungen "/ simpleUrlWelcome" und "/ * / simpleUrlWelcome" der "Welcome" -Bohne zu :

@Configuration public class SimpleUrlHandlerMappingConfig { @Bean public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); Map urlMap = new HashMap(); urlMap.put("/simpleUrlWelcome", welcome()); simpleUrlHandlerMapping.setUrlMap(urlMap); return simpleUrlHandlerMapping; } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

Alternativ ist hier die entsprechende XML-Konfiguration:

   /simpleUrlWelcome=welcome /*/simpleUrlWelcome=welcome    

Es ist wichtig zu beachten, dass in der XML-Konfiguration eine Zuordnung zwischen dem Tag "" in einer von der Klasse " java.util.Properties" akzeptierten Form erfolgen muss und der folgenden Syntax folgen sollte: path = Handler_Bean_Name .

Die URL sollte normalerweise mit einem führenden Schrägstrich versehen sein. Wenn der Pfad jedoch nicht mit einem beginnt, fügt Spring MVC ihn automatisch hinzu.

Eine andere Möglichkeit, das obige Beispiel in XML zu konfigurieren, besteht darin, die Eigenschaft "props" anstelle von "value" zu verwenden . Requisiten haben eine Liste mit "Requisiten" -Tags, in denen jeweils eine Zuordnung definiert ist, wobei "Schlüssel" auf die zugeordnete URL verweist und der Wert des Tags der Name der Bean ist.

   welcome welcome   

Der folgende Testfall stellt sicher , dass Anfragen an „/ simpleUrlWelcome “ durch „behandelt WelcomeController“ , die einen Blick Namen genannt kehrt „welcome“ :

public class SimpleUrlMappingConfigTest { // ... @Test public void whenSimpleUrlMapping_thenMappedOK() { mockMvc.perform(get("/simpleUrlWelcome")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

4. ControllerClassNameHandlerMapping (in Spring 5 entfernt)

Die ControllerClassNameHandlerMapping ordnet die URL einer registrierten Controller-Bean (oder einem Controller, der mit der Annotation @Controller versehen ist ) zu, die denselben Namen hat oder mit diesem beginnt.

Dies kann in vielen Szenarien praktischer sein, insbesondere bei einfachen Controller-Implementierungen, die einen einzelnen Anforderungstyp verarbeiten. Die von Spring MVC verwendete Konvention besteht darin, den Namen der Klasse zu verwenden und das Suffix "Controller" zu entfernen , dann den Namen in Kleinbuchstaben zu ändern und ihn als Zuordnung mit einem führenden "/" zurückzugeben .

Zum Beispiel würde "WelcomeController" als Zuordnung zu "/ welcome *" zurückkehren , dh zu einer beliebigen URL, die mit "welcome" beginnt .

Konfigurieren wir ControllerClassNameHandlerMapping :

@Configuration public class ControllerClassNameHandlerMappingConfig { @Bean public ControllerClassNameHandlerMapping controllerClassNameHandlerMapping() { return new ControllerClassNameHandlerMapping(); } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

Beachten Sie, dass ControllerClassNameHandlerMapping ab Spring 4.3 zugunsten von annotationsgesteuerten Handlermethoden veraltet ist .

Ein weiterer wichtiger Hinweis ist, dass Controller-Namen immer in Kleinbuchstaben zurückgegeben werden (abzüglich des Suffixes „Controller“). Wenn wir also einen Controller namens " WelcomeBaeldungController " haben, werden nur Anfragen an "/ welcomebaeldung" und nicht an "/ welcomeBaeldung" verarbeitet .

Sowohl in der Java-Konfiguration als auch in der XML-Konfiguration definieren wir die ControllerClassNameHandlerMapping- Bean und registrieren die Beans für die Controller, die wir zur Verarbeitung von Anforderungen verwenden. Wir registrieren auch eine Bean vom Typ "WelcomeController" und diese Bean verarbeitet alle Anfragen, die mit "/ welcome" beginnen .

Hier ist die entsprechende XML-Konfiguration:

Bei Verwendung der obigen Konfiguration werden Anfragen an "/ welcome " vom " WelcomeController " bearbeitet .

Der folgende Code stellt sicher, dass Anfragen an "/ welcome *" wie "/ welcometest " von " WelcomeController " verarbeitet werden, der einen Ansichtsnamen mit dem Namen " welcome " zurückgibt :

public class ControllerClassNameHandlerMappingTest { // ... @Test public void whenControllerClassNameMapping_thenMappedOK() { mockMvc.perform(get("/welcometest")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

5. Prioritäten konfigurieren

Spring MVC framework allows more than one implementation of HandlerMapping interface at the same time.

Let us create a configuration and register two controllers, both mapped to URL “/welcome”, only using different mapping and returning different view names:

@Configuration public class HandlerMappingDefaultConfig { @Bean("/welcome") public BeanNameHandlerMappingController beanNameHandlerMapping() { return new BeanNameHandlerMappingController(); } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

With no explicit handler mapper registered, a default BeanNameHandlerMapping will be used. Let us assert this behaviour with the test:

@Test public void whenConfiguringPriorities_thenMappedOK() { mockMvc.perform(get("/welcome")) .andExpect(status().isOk()) .andExpect(view().name("bean-name-handler-mapping")); } 

If we explicitly register a different handler mapper, the default mapper will be overridden. However, it is interesting to see what happens when two mappers are explicitly registered:

@Configuration public class HandlerMappingPrioritiesConfig { @Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() { BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = new BeanNameUrlHandlerMapping(); return beanNameUrlHandlerMapping; } @Bean public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); Map urlMap = new HashMap(); urlMap.put("/welcome", simpleUrlMapping()); simpleUrlHandlerMapping.setUrlMap(urlMap); return simpleUrlHandlerMapping; } @Bean public SimpleUrlMappingController simpleUrlMapping() { return new SimpleUrlMappingController(); } @Bean("/welcome") public BeanNameHandlerMappingController beanNameHandlerMapping() { return new BeanNameHandlerMappingController(); } }

To get the control over which mapping is used, the priorities are set using setOrder(int order) method. This method takes one int parameter where lower value mean higher priority.

In XML configuration you can configure priorities by using a property called “order”:

Let us add order properties to handler mapping beans, via following beanNameUrlHandlerMapping.setOrder(1) and simpleUrlHandlerMapping.setOrder(0). The lower value of the order property reflects higher precedence. Let us assert new behaviour with the test:

@Test public void whenConfiguringPriorities_thenMappedOK() { mockMvc.perform(get("/welcome")) .andExpect(status().isOk()) .andExpect(view().name("simple-url-handler-mapping")); }

Beim Testen der obigen Konfiguration sehen Sie, dass Anforderungen an "/ welcome" von der SimpleUrlHandlerMapping- Bean verarbeitet werden, die einen SimpleUrlHandlerController aufruft und eine einfache URL-Handler-Zuordnungsansicht zurückgibt . Wir können das BeanNameHandlerMapping einfach so konfigurieren , dass es Vorrang hat, indem wir die Werte der order- Eigenschaft entsprechend anpassen .

6. Fazit

In diesem Artikel haben wir erläutert, wie die URL-Zuordnung im Spring MVC-Framework behandelt wird, indem die verschiedenen Implementierungen im Framework untersucht wurden.

Den Code zu diesem Artikel finden Sie auf GitHub.