Gids voor Mappings van Spring Handler

1. Inleiding

In Spring MVC, de DispatcherServlet fungeert als frontcontroller - ontvangt alle inkomende HTTP-verzoeken en verwerkt deze.

Simpel gezegd, de verwerking vindt plaats door de verzoeken door te geven aan de relevante component met behulp van handlertoewijzingen.

HandlerMapping is een interface die een mapping definieert tussen verzoeken en handlerobjecten. Hoewel het Spring MVC-framework enkele kant-en-klare implementaties biedt, kan de interface door ontwikkelaars worden geïmplementeerd om een ​​aangepaste kaartstrategie te bieden.

Dit artikel bespreekt enkele van de implementaties die door Spring MVC worden geboden, namelijk BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping, ControllerClassNameHandlerMapping, hun configuratie en de verschillen daartussen.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping is de standaard HandlerMapping implementatie. BeanNameUrlHandlerMapping maps verzoeken URL's naar bonen met dezelfde naam.

Deze specifieke mapping heeft ondersteuning voor directe naamvergelijking en ook voor patroonvergelijking met behulp van het "*" -patroon.

Bijvoorbeeld een inkomende URL "/ Foo" wordt toegewezen aan een boon met de naam "/ Foo". Een voorbeeld van patroontoewijzing is het toewijzen van verzoeken aan "/ Foo *" tot bonen waarvan de naam begint met "/ Foo" Leuk vinden "/ Foo2 /" of "/ FooOne /".

Laten we dit voorbeeld hier configureren en een bean-controller registreren die verzoeken afhandelt naar "/ BeanNameUrl":

@Configuration openbare klasse BeanNameUrlHandlerMappingConfig {@Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping () {retourneer nieuwe BeanNameUrlHandlerMapping (); } @Bean ("/ beanNameUrl") openbare WelcomeController welcome () {retourneer nieuwe WelcomeController (); }}

Dit is het XML-equivalent van de bovenstaande op Java gebaseerde configuratie:

Het is belangrijk op te merken dat in beide configuraties een boon definiëren voor BeanNameUrlHandlerMapping is niet nodig zoals geleverd door Spring MVC. Het verwijderen van deze bean-definitie levert geen problemen op en verzoeken worden nog steeds toegewezen aan hun geregistreerde handlerbeans.

Nu alle verzoeken aan "/ BeanNameUrl" wordt doorgestuurd DispatcherServlet naar "WelkomController“. WelkomController geeft een weergavenaam terug met de naam 'Welkom“.

De volgende code test deze configuratie en zorgt ervoor dat de juiste viewnaam wordt geretourneerd:

openbare klasse BeanNameMappingConfigTest {// ... @Test openbare leegte whenBeanNameMapping_thenMappedOK () {mockMvc.perform (get ("/ beanNameUrl")) .andExpect (status (). isOk ()) .andExpect (view (). name (" Welkom")); }}

3. SimpleUrlHandlerMapping

Vervolgens de SimpleUrlHandlerMapping is het meest flexibel HandlerMapping implementatie. Het maakt directe en declaratieve toewijzing mogelijk tussen bean-instanties en URL's of tussen bean-namen en URL's.

Laten we verzoeken in kaart brengen "/ SimpleUrlWelcome" en "/ * / SimpleUrlWelcome" naar de "Welkom" Boon:

@Configuration openbare klasse SimpleUrlHandlerMappingConfig {@Bean openbaar SimpleUrlHandlerMapping simpleUrlHandlerMapping () {SimpleUrlHandlerMapping simpleUrlHandlerMapping = nieuwe SimpleUrlHandlerMapping (); Map urlMap = nieuwe HashMap (); urlMap.put ("/ simpleUrlWelcome", welkom ()); simpleUrlHandlerMapping.setUrlMap (urlMap); retourneer simpleUrlHandlerMapping; } @Bean public WelcomeController welcome () {retourneer nieuwe WelcomeController (); }}

Als alternatief is hier de equivalente XML-configuratie:

   / simpleUrlWelcome = welkom / * / simpleUrlWelcome = welkom 

Het is belangrijk op te merken dat in de XML-configuratie een mapping tussen “” tag moet worden gedaan in een vorm die is geaccepteerd door java.util.Properties class en het zou de syntaxis moeten volgen: path = Handler_Bean_Name.

De URL zou normaal gesproken met een schuine streep moeten zijn, maar als het pad niet met één begint, voegt Spring MVC het automatisch toe.

Een andere manier om het bovenstaande voorbeeld in XML te configureren, is door de "rekwisieten" eigendom in plaats van "waarde". Rekwisieten hebben een lijst met "Prop" tag waarbij elk een toewijzing definieert waar "sleutel" verwezen naar de toegewezen URL en de waarde van de tag is de naam van de bean.

   welkom welkom 

De volgende testcase zorgt ervoor dat verzoeken om “/simpleUrlWelkom"Wordt afgehandeld door"WelcomeController ” die een weergavenaam retourneert met de naam "Welkom" :

openbare klasse SimpleUrlMappingConfigTest {// ... @Test openbare void whenSimpleUrlMapping_thenMappedOK () {mockMvc.perform (get ("/ simpleUrlWelcome")) .andExpect (status (). isOk ()) .andExpect (view (). name (" Welkom")); }}

4. ControllerClassNameHandlerMapping (verwijderd in voorjaar 5)

De ControllerClassNameHandlerMapping wijst URL toe aan een geregistreerde controllerbean (of een controller die is geannoteerd met de @Controller annotatie) die dezelfde naam heeft of begint met.

Het kan in veel scenario's handiger zijn, vooral voor eenvoudige controllerimplementaties die een enkel verzoektype verwerken. De conventie die door Spring MVC wordt gebruikt, is om de naam van de klasse te gebruiken en de "Controller" achtervoegsel, verander vervolgens de naam in kleine letters en retourneer het als de afbeelding met een voorloop “/”.

Bijvoorbeeld "WelcomeController" zou terugkeren als mapping naar "/Welkom*", d.w.z. naar elke URL die begint met "Welkom".

Laten we configureren ControllerClassNameHandlerMapping:

@Configuration openbare klasse ControllerClassNameHandlerMappingConfig {@Bean openbare ControllerClassNameHandlerMapping controllerClassNameHandlerMapping () {retourneer nieuwe ControllerClassNameHandlerMapping (); } @Bean public WelcomeController welcome () {retourneer nieuwe WelcomeController (); }}

Let daar op ControllerClassNameHandlerMapping is verouderd vanaf Spring 4.3 in het voordeel van annotatiegestuurde afhandelingsmethoden.

Een andere belangrijke opmerking is dat namen van controllers altijd in kleine letters worden geretourneerd (minus het achtervoegsel "Controller"). Dus als we een controller hebben met de naam 'WelkomBaeldungController“, Het behandelt alleen verzoeken aan "/ Welcomebaeldung" en niet om "/ WelcomeBaeldung".

In zowel Java-configuratie als XML-configuratie hieronder definiëren we ControllerClassNameHandlerMapping bean en registreer bonen voor de controllers die we zullen gebruiken om verzoeken af ​​te handelen. We registreren ook een soort boon "WelcomeController" en die boon behandelt alle verzoeken die beginnen met "/Welkom".

Hier is de equivalente XML-configuratie:

Bij gebruik van de bovenstaande configuratie, verzoeken om “/Welkom"Wordt afgehandeld door de"WelkomController“.

De volgende code zorgt ervoor dat verzoeken om “/Welkom*" zoals "/welkomsttest"Wordt afgehandeld door" WelcomeController "die een weergavenaam retourneert met de naam"Welkom“:

openbare klasse ControllerClassNameHandlerMappingTest {// ... @Test openbare leegte whenControllerClassNameMapping_thenMappedOK () {mockMvc.perform (get ("/ welcometest")) .andExpect (status (). isOk ()) .andExpect (view (). name (" Welkom")); }}

5. Prioriteiten configureren

Spring MVC-framework maakt meer dan één implementatie van HandlerMapping interface tegelijkertijd.

Laten we een configuratie maken en twee controllers registreren, beide toegewezen aan de URL "/ welcome", met alleen verschillende toewijzingen en het retourneren van verschillende weergavenamen:

@Configuration openbare klasse HandlerMappingDefaultConfig {@Bean ("/ welcome") openbare BeanNameHandlerMappingController beanNameHandlerMapping () {retourneer nieuwe BeanNameHandlerMappingController (); } @Bean public WelcomeController welcome () {retourneer nieuwe WelcomeController (); }}

Als er geen expliciete handlertoewijzing is geregistreerd, is dit een standaard BeanNameHandlerMapping zal gebruikt worden. Laten we dit gedrag bevestigen met de test:

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

Als we expliciet een andere handler-mapper registreren, wordt de standaard mapper overschreven. Het is echter interessant om te zien wat er gebeurt als twee mappers expliciet worden geregistreerd:

@Configuration openbare klasse HandlerMappingPrioritiesConfig {@Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping () {BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = nieuwe BeanNameUrlHandlerMapping (); geef beanNameUrlHandlerMapping terug; } @Bean openbaar SimpleUrlHandlerMapping simpleUrlHandlerMapping () {SimpleUrlHandlerMapping simpleUrlHandlerMapping = nieuwe SimpleUrlHandlerMapping (); Map urlMap = nieuwe HashMap (); urlMap.put ("/ welkom", simpleUrlMapping ()); simpleUrlHandlerMapping.setUrlMap (urlMap); retourneer simpleUrlHandlerMapping; } @Bean openbare SimpleUrlMappingController simpleUrlMapping () {retourneer nieuwe SimpleUrlMappingController (); } @Bean ("/ welcome") openbare BeanNameHandlerMappingController beanNameHandlerMapping () {retourneer nieuwe BeanNameHandlerMappingController (); }}

Om controle te krijgen over welke mapping wordt gebruikt, worden de prioriteiten bepaald met setOrder (int order) methode. Deze methode duurt één int parameter waarbij een lagere waarde een hogere prioriteit betekent.

In XML-configuratie kunt u prioriteiten configureren met behulp van een eigenschap met de naam "bestellen":

Laten we toevoegen bestellen eigenschappen aan handler mapping bonen, via volgende beanNameUrlHandlerMapping.setOrder (1) en simpleUrlHandlerMapping.setOrder (0). De lagere waarde van de bestellen eigenschap geeft een hogere prioriteit weer. Laten we met de test nieuw gedrag laten gelden:

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

Bij het testen van de bovenstaande configuratie, zie je dat verzoeken om "/Welkom" zal worden afgehandeld door SimpleUrlHandlerMapping bean die een SimpleUrlHandlerController en keert terug simple-url-handler-mapping visie. We kunnen het BeanNameHandlerMapping om voorrang te krijgen door de waarden van dienovereenkomstig aan te passen bestellen eigendom.

6. Conclusie

In dit artikel hebben we besproken hoe URL-toewijzing wordt afgehandeld in het Spring MVC-framework door de verschillende implementaties in het framework te verkennen.

De code bij dit artikel is te vinden op GitHub.