Panduan Pemetaan Spring Handler

1. Pengenalan

Pada Spring MVC, DispatcherServlet bertindak sebagai pengawal depan - menerima semua permintaan HTTP yang masuk dan memprosesnya.

Ringkasnya, pemprosesan berlaku dengan menyampaikan permintaan ke komponen yang relevan dengan bantuan pemetaan pengendali .

HandlerMapping adalah antara muka yang menentukan pemetaan antara permintaan dan objek pengendali. Walaupun rangka Spring MVC menyediakan beberapa implementasi siap pakai, antara muka dapat dilaksanakan oleh pemaju untuk menyediakan strategi pemetaan yang disesuaikan.

Artikel ini membincangkan beberapa pelaksanaan yang disediakan oleh Spring MVC iaitu BeanNameUrlHandlerMapping , SimpleUrlHandlerMapping , ControllerClassNameHandlerMapping , konfigurasi mereka, dan perbezaan di antara mereka.

2. Pemetaan BeanNameUrlHandler

BeanNameUrlHandlerMapping adalah pelaksanaan HandlerMapping lalai . Peta Pemetaan BeanNameUrlHandler meminta URL kepada kacang dengan nama yang sama.

Pemetaan khusus ini mempunyai sokongan untuk pencocokan nama langsung dan juga untuk pencocokan pola menggunakan pola "*".

Contohnya, URL masuk "/ foo" memetakan kacang yang disebut "/ foo" . Contoh pemetaan corak adalah pemetaan permintaan untuk “/ foo *” ke kacang dengan nama yang dimulai dengan “/ foo” seperti “/ foo2 /” atau “/ fooOne /” .

Mari konfigurasikan contoh ini di sini dan daftarkan pengawal kacang yang menangani permintaan ke "/ beanNameUrl" :

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

Ini adalah setara XML dari konfigurasi berasaskan Java di atas:

Penting untuk diperhatikan bahawa dalam kedua-dua konfigurasi ini, penentuan kacang untuk BeanNameUrlHandlerMapping tidak diperlukan kerana ia disediakan oleh Spring MVC. Mengeluarkan definisi kacang ini tidak akan menyebabkan masalah dan permintaan masih akan dipetakan ke kacang pengendali yang didaftarkan.

Sekarang semua permintaan untuk "/ beanNameUrl" akan diteruskan oleh DispatcherServlet ke " WelcomeController ". WelcomeController mengembalikan nama pandangan yang disebut " selamat datang ".

Kod berikut menguji konfigurasi ini dan memastikan bahawa nama paparan yang betul dikembalikan:

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

3. Pemetaan SimpleUrlHandler

Seterusnya, SimpleUrlHandlerMapping adalah pelaksanaan HandlerMapping yang paling fleksibel . Ini memungkinkan pemetaan langsung dan deklaratif antara contoh kacang dan URL atau antara nama kacang dan URL.

Mari memetakan permintaan "/ simpleUrlWelcome" dan "/ * / simpleUrlWelcome" ke kacang "selamat datang" :

@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(); } }

Sebagai alternatif, berikut adalah konfigurasi XML yang setara:

   /simpleUrlWelcome=welcome /*/simpleUrlWelcome=welcome    

Penting untuk diperhatikan bahawa dalam konfigurasi XML, pemetaan antara tag "" mesti dilakukan dalam bentuk yang diterima oleh kelas java.util.Properties dan harus mengikuti sintaks: path = Handler_Bean_Name .

URL biasanya harus dengan garis miring utama, namun, jika jalan tidak dimulai dengan satu, Spring MVC menambahkannya secara automatik.

Cara lain untuk mengkonfigurasi contoh di atas dalam XML adalah dengan menggunakan properti "alat peraga" dan bukan "nilai" . Alat peraga mempunyai senarai tag "prop" di mana masing-masing menentukan pemetaan di mana "kunci" merujuk pada URL yang dipetakan dan nilai tag adalah nama kacang.

   welcome welcome   

Kes ujian berikut memastikan bahawa permintaan untuk "/ simpleUrlWelcome " ditangani oleh " WelcomeController" yang mengembalikan nama pandangan yang disebut "selamat datang" :

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

4. ControllerClassNameHandlerMapping (dikeluarkan pada musim bunga 5)

The ControllerClassNameHandlerMapping maps URL kepada kacang berdaftar pengawal (atau pengawal dijelaskan dengan @Controller anotasi) yang mempunyai, atau bermula dengan, nama yang sama.

Ini boleh menjadi lebih mudah dalam banyak senario terutamanya untuk pelaksanaan pengawal sederhana yang menangani satu jenis permintaan. Konvensyen yang digunakan oleh Spring MVC adalah menggunakan nama kelas dan menghapus akhiran "Pengawal" , kemudian menukar nama menjadi huruf kecil dan mengembalikannya sebagai pemetaan dengan "/" terkemuka .

Sebagai contoh "WelcomeController" akan kembali sebagai pemetaan ke "/ welcome *" , iaitu ke mana-mana URL yang diawali dengan "selamat datang" .

Mari konfigurasikan Pemetaan ControllerClassNameHandler :

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

Perhatikan bahawa ControllerClassNameHandlerMapping tidak digunakan lagi dari Spring 4.3 untuk kaedah pengendali yang didorong oleh anotasi.

Catatan penting lain adalah bahawa nama pengawal akan selalu dikembalikan dalam huruf kecil (tolak akhiran "Pengawal"). Oleh itu, jika kita memiliki pengawal yang disebut " WelcomeBaeldungController ", itu hanya akan menangani permintaan untuk "/ welcomebaeldung" dan bukan untuk "/ welcomeBaeldung" .

Dalam konfigurasi Java dan konfigurasi XML di bawah ini, kami menentukan kacang ControllerClassNameHandlerMapping dan mendaftar kacang untuk pengawal yang akan kami gunakan untuk menangani permintaan. Kami juga mendaftarkan kacang jenis "WelcomeController" dan kacang itu akan menangani semua permintaan yang dimulai dengan "/ selamat datang" .

Inilah konfigurasi XML yang setara:

Ketika menggunakan konfigurasi di atas, permintaan untuk "/ selamat datang " akan ditangani oleh " WelcomeController ".

Kod berikut akan memastikan bahawa permintaan untuk "/ welcome *" seperti "/ welcometest " ditangani oleh "WelcomeController" yang mengembalikan nama pandangan yang disebut " selamat datang ":

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

5. Mengkonfigurasi Keutamaan

Rangka kerja Spring MVC membolehkan lebih daripada satu pelaksanaan antara muka HandlerMapping pada masa yang sama.

Mari kita buat konfigurasi dan daftarkan dua pengawal, keduanya dipetakan ke URL "/ welcome", hanya menggunakan pemetaan yang berbeza dan mengembalikan nama pandangan yang berbeza:

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

Tanpa pemalsu pengendali eksplisit didaftarkan, BeanNameHandlerMapping lalai akan digunakan. Mari kita tegaskan tingkah laku ini dengan ujian:

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

Sekiranya kita secara jelas mendaftarkan mapper pengendali yang berbeza, mapper lalai akan diganti. Walau bagaimanapun, sangat menarik untuk melihat apa yang berlaku apabila dua pemeta didaftarkan secara eksplisit:

@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(); } }

Untuk mendapatkan kawalan pemetaan mana yang digunakan, keutamaan ditetapkan menggunakan kaedah setOrder (int order) . Kaedah ini mengambil satu parameter int di mana nilai yang lebih rendah bermaksud keutamaan yang lebih tinggi.

Dalam konfigurasi XML, anda dapat mengkonfigurasi keutamaan dengan menggunakan sifat yang disebut "pesanan" :

Mari kita tambahkan sifat pesanan ke pengendali kacang pemetaan, melalui beanNameUrlHandlerMapping.setOrder berikut (1) dan simpleUrlHandlerMapping.setOrder (0). Nilai harta pesanan yang lebih rendah menunjukkan keutamaan yang lebih tinggi. Mari kita tegaskan tingkah laku baru dengan ujian:

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

Semasa menguji konfigurasi di atas, anda melihat bahawa permintaan untuk "/ selamat datang" akan ditangani oleh kacang SimpleUrlHandlerMapping yang memanggil SimpleUrlHandlerController dan mengembalikan pandangan pemetaan url sederhana-url . Kita boleh mengkonfigurasi BeanNameHandlerMapping dengan mudah untuk diutamakan dengan menyesuaikan nilai properti pesanan dengan sewajarnya .

6. Kesimpulannya

Dalam artikel ini kita membincangkan bagaimana pemetaan URL ditangani dalam rangka kerja Spring MVC dengan meneroka berbagai implementasi dalam kerangka tersebut.

Kod yang menyertakan artikel ini boleh didapati di GitHub.