Bevezetés a Spring DispatcherServlet-be

1. Bemutatkozás

Egyszerűen fogalmazva a Első vezérlő tervezési minta, egyetlen vezérlő az felelős a bejövők irányításáért HttpRequests az alkalmazás összes többi vezérlőjéhez és kezelőjéhez.

Tavaszi DispatcherServlet végrehajtja ezt a mintát, ezért felelős a megfelelő koordinálásáért HttpRequests jobbkezelőiknek.

Ebben a cikkben fogjuk vizsgálja meg a tavaszt DispatcherServlet's kérjen feldolgozási munkafolyamatot és hogyan lehet megvalósítani az ebben a munkafolyamatban résztvevő interfészeket.

2. DispatcherServlet Kérelem feldolgozása

Lényegében a DispatcherServlet kezeli a bejövőt HttpRequest, átruházza a kérést, és a konfiguráltnak megfelelően feldolgozza a kérést HandlerAdapter interfészek amelyeket a Spring alkalmazáson belül hajtottak végre, valamint a kezelőket, a vezérlő végpontokat és a válaszobjektumokat meghatározó kísérő megjegyzésekkel együtt.

Nézzük meg alaposabban, hogyan a DispatcherServlet egy komponenst feldolgoz:

  • a WebApplicationContext társítva a DispatcherServlet a kulcs alatt DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE megkeresi és elérhetővé teszi a folyamat összes eleme számára
  • A DispatcherServlet megtalálja a HandlerAdapter a diszpécser számára konfigurált felület getHandler () - mindegyik megtalált és konfigurált megvalósítás a kérelmet keresztül kezeli fogantyú() a folyamat hátralévő részén keresztül
  • a LocaleResolver opcionálisan kapcsolódik ahhoz a kéréshez, amely lehetővé teszi a folyamat elemeinek a területi beállítás megoldását
  • a ThemeResolver opcionálisan kötődik ahhoz a kérelemhez, hogy az elemek, például a nézetek határozzák meg, hogy melyik témát használják
  • Ha egy MultipartResolver meg van adva, a kérelmet megvizsgálják MultipartFiles - bármely találtat a-ba csomagolják MultipartHttpServletRequest további feldolgozásra
  • HandlerExceptionResolver - ban deklarált megvalósítások WebApplicationContext felveszi azokat a kivételeket, amelyek a kérelem feldolgozása során felmerülnek

Tudjon meg többet a regisztráció és a beállítás minden módjáról DispatcherServlet itt.

3. HandlerAdapter Interfészek

A HandlerAdapter az interfész megkönnyíti a vezérlők, a kiszolgálók, HttpRequests, és a HTTP-útvonalakat több speciális interfészen keresztül. A HandlerAdapter interfész tehát lényeges szerepet játszik a DispatcherServlet kérjen feldolgozási munkafolyamatot.

Először mindegyik HandlerAdapter megvalósítás kerül a HandlerExecutionChain a diszpécsertől getHandler () módszer. Ezután mindegyik ilyen megvalósítás fogantyú() a HttpServletRequest objektum, ahogy a végrehajtási lánc halad.

A következő szakaszokban néhány legfontosabbat és leggyakrabban használtat tárunk fel HandlerAdapterek részletesebben.

3.1. Leképezések

A hozzárendelések megértéséhez először meg kell vizsgálnunk, hogyan kell annotálni a vezérlőket, mivel a vezérlők annyira elengedhetetlenek a HandlerMapping felület.

A SimpleControllerHandlerAdapter lehetővé teszi egy kontroller megvalósítását, kifejezetten a nélkül @Vezérlő annotáció.

A RequestMappingHandlerAdapter támogatja a @RequestMapping annotáció.

Összpontosítunk a @Vezérlő megjegyzés itt, de hasznos forrás, számos példával a SimpleControllerHandlerAdapter is elérhető.

A @RequestMapping az annotáció meghatározza azt a konkrét végpontot, amelyen a kezelő elérhető lesz belül WebApplicationContext társul hozzá.

Lássunk egy példát a Vezérlő amely kiteszi és kezeli a ’/ User / example’ végpont:

@Controller @RequestMapping ("/ user") @ResponseBody public class UserController {@GetMapping ("/ example") public User fetchUserExample () {// ...}}

A. Által megadott útvonalak @RequestMapping az annotációkat az HandlerMapping felület.

Az URL-ek felépítése természetesen viszonyul a DispatcherServlet maga - és a servlet feltérképezése határozza meg.

Így, ha a DispatcherServlet „/” -re van leképezve, akkor az összes leképezést lefedi ez a leképezés.

Ha azonban a szervlet leképezés/ diszpécser‘Helyett, akkor bármelyik @RequestMapping a kommentárok viszonylagosan viszonyulnak a gyökér URL-hez.

Ne feledje, hogy a „/” nem azonos a „/ *” szóval a servlet leképezésekhez! A '/' az alapértelmezett leképezés, és az összes URL-t kiteszi a diszpécser felelősségi körébe.

A ‘/ *’ sok új Spring fejlesztő számára zavaró. Nem határozza meg, hogy az azonos URL-kontextussal rendelkező összes út a diszpécser felelősségi körébe tartozik-e. Ehelyett felülírja és figyelmen kívül hagyja a többi diszpécser leképezést. Tehát a „/ example” 404-esként fog megjelenni!

Amiatt, abból az okból, A „/ *” szót csak nagyon korlátozott körülmények között szabad használni (mint például egy szűrő konfigurálása).

3.2. HTTP kérések kezelése

A. Fő felelőssége DispatcherServlet a bejövő küldése HttpRequests a helyes kezelőknek a @Vezérlő vagy @RestController annotációk.

Megjegyzendő, hogy a fő különbség a @Vezérlő és @RestController az, hogyan jön létre a válasz - az @RestController meghatározza is @ResponseBody alapértelmezés szerint.

Itt található egy írás, ahol sokkal mélyebben elmélyülünk a Spring vezérlőivel kapcsolatban.

3.3. A ViewResolver Felület

A ViewResolver a DispatcherServlet konfigurációs beállításként egy ApplicationContext tárgy.

A ViewResolver meghatározza, hogy a diszpécser milyen nézeteket szolgál fel, és azt is, hogy honnan.

Itt van egy példa a konfigurációról, amelyet be fogunk helyezni a mi AppConfig JSP oldalak megjelenítéséhez:

@Configuration @EnableWebMvc @ComponentScan ("com.baeldung.springdispatcherservlet") nyilvános osztályú AppConfig valósítja meg a WebMvcConfigurer {@Bean public UrlBasedViewResolver viewResolver () {UrlBasedViewResolver resolver = new UrlBasedV; resolver.setPrefix ("/ WEB-INF / nézet /"); resolver.setSuffix (". jsp"); resolver.setViewClass (JstlView.class); return resolver; }}

Nagyon egyenesen előre! Ennek három fő része van:

  1. az előtag beállítása, amely beállítja az alapértelmezett URL-elérési utat a beállított nézetek megtalálásához
  2. az utótaggal beállított alapértelmezett nézettípus
  3. nézetosztály beállítása a felbontón, amely lehetővé teszi olyan technológiák, mint a JSTL vagy a Tiles, társítását a renderelt nézetekkel

Az egyik gyakori kérdés az, hogy mennyire pontosan a diszpécser ViewResolverés a projekt könyvtár általános szerkezete összefügg. Vessünk egy pillantást az alapokra.

Itt van egy példa az InternalViewResolver a Spring XML konfigurációjával:

Példánk kedvéért feltételezzük, hogy alkalmazásunk a következő webhelyen található:

// localhost: 8080 /

Ez az alapértelmezett cím és port egy lokálisan hosztolt Apache Tomcat kiszolgálóhoz.

Feltéve, hogy az alkalmazásunkat meghívják diszpécser-példa-1.0.0, JSP nézeteink elérhetők lesznek:

//localhost:8080/dispatcherexample-1.0.0/jsp/

Ezeknek a nézeteknek az útvonala a Maven-lel folytatott tavaszi projekten belül a következő:

src - | fő - | java források webapp - | jsp WEB-INF

A nézetek alapértelmezett helye a WEB-INF. A mi számára megadott útvonal InternalViewResolver a fenti részletben meghatározza az ‘src / main / webapp’ alkönyvtárát, amelyben a nézetei elérhetőek lesznek.

3.4. A LocaleResolver Felület

A munkamenet-, kérelem- vagy cookie-adatok diszpécserünk számára történő testreszabásának elsődleges módja a LocaleResolver felület.

CookieLocaleResolver olyan megvalósítás, amely lehetővé teszi a hontalan alkalmazás tulajdonságainak konfigurálását cookie-k segítségével. Tegyük hozzá AppConfig.

@Bean public CookieLocaleResolver cookieLocaleResolverExample () {CookieLocaleResolver localeResolver = new CookieLocaleResolver (); localeResolver.setDefaultLocale (Locale.ENGLISH); localeResolver.setCookieName ("locale-cookie-resolver-example"); localeResolver.setCookieMaxAge (3600); return localeResolver; } @Bean public LocaleResolver sessionLocaleResolver () {SessionLocaleResolver localeResolver = new SessionLocaleResolver (); localeResolver.setDefaultLocale (Locale.US); localResolver.setDefaultTimeZone (TimeZone.getTimeZone ("UTC")); return localeResolver; } 

SessionLocaleResolver lehetővé teszi a munkamenet-specifikus konfigurációt egy állapotos alkalmazásban.

A setDefaultLocale() módszer egy földrajzi, politikai vagy kulturális régiót képvisel, míg setDefaultTimeZone() meghatározza a relevánsat Időzóna objektum az alkalmazáshoz Bab kérdéses.

Mindkét módszer elérhető a LocaleResolver.

3.5. A ThemeResolver Felület

A tavasz stilisztikai témát nyújt nézeteinkhez.

Vizsgáljuk meg, hogyan konfigurálhatjuk diszpécserünket a témák kezelésére.

Első, állítsuk be a statikus témájú fájljaink megkereséséhez és használatához szükséges összes konfigurációt. Be kell állítanunk a statikus erőforrás helyét ThemeSource a tényleges konfigurálásához Témák maguk (Téma objektumok tartalmazzák a fájlokban előírt összes konfigurációs információt). Add hozzá ezt a AppConfig:

@Orride public void addResourceHandlers (ResourceHandlerRegistry registry) {register.addResourceHandler ("/ resources / **") .addResourceLocations ("/", "/ resources /") .setCachePeriod (3600) .resourceChain (true) .addResolver (új PathRes ()); } @Bean public ResourceBundleThemeSource themeSource () {ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource (); themeSource.setDefaultEncoding ("UTF-8"); themeSource.setBasenamePrefix ("témák"); return themeSource; } 

A. Által kezelt kérelmek DispatcherServlet módosíthatja a témát egy megadott paraméter segítségével setParamName() elérhető a ThemeChangeInterceptor tárgy. Hozzáadás ehhez: AppConfig:

@Bean public CookieThemeResolver themeResolver () {CookieThemeResolver resolver = new CookieThemeResolver (); resolver.setDefaultThemeName ("példa"); resolver.setCookieName ("példa-téma-süti"); return resolver; } @Bean public ThemeChangeInterceptor themeChangeInterceptor () {ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor (); interceptor.setParamName ("téma"); visszatérő elfogó; } @Orride public void addInterceptors (InterceptorRegistry registry) {register.addInterceptor (themeChangeInterceptor ()); } 

A következő JSP címke hozzáadásra kerül a nézetünkhöz, hogy megjelenjen a helyes stílus:

A következő URL-kérés a példa téma a „téma” paraméter használatával átadva a konfiguráltunknak ThemeChangeIntercepter:

//localhost:8080/dispatcherexample-1.0.0/?theme=example

3.6. A MultipartResolver Felület

A MultipartResolver a megvalósítás megvizsgálja a többrészes kérelmet, és beburkolja a MultipartHttpServletRequest további feldolgozásra a folyamat más elemei által, ha legalább egy többrészes anyag található. Hozzáadás ehhez: AppConfig:

@Bean public CommonsMultipartResolver multipartResolver () dobja az IOException-t {CommonsMultipartResolver resolver = new CommonsMultipartResolver (); resolver.setMaxUploadSize (10000000); return resolver; } 

Most, hogy konfiguráltuk MultipartResolver bab, állítsunk be egy vezérlőt a feldolgozáshoz MultipartFile kérések:

@Controller public class MultipartController {@Autowired ServletContext context; @PostMapping ("/ upload") public ModelAndView FileuploadController (@RequestParam ("file") MultipartFile file) dobja az IOException {ModelAndView modelAndView = new ModelAndView ("index"); InputStream in = file.getInputStream (); Karaktersorozat = új fájl ("."). GetAbsolutePath (); FileOutputStream f = new FileOutputStream (elérési útvonal.struktúra (0, elérési út.hossz () - 1) + "/ feltöltések /" + fájl.getOriginalFilename ()); int ch; míg ((ch = beolvasva ())! = -1) {f.írja (ch); } f.öblítés (); f. bezár (); körülkerít(); modelAndView.getModel () .put ("üzenet", "A fájl feltöltése sikeresen megtörtént!"); return modelAndView; }}

Használhatunk normál űrlapot egy fájl elküldéséhez a megadott végponthoz. A feltöltött fájlok a „CATALINA_HOME / bin / uploads” mappában lesznek elérhetők.

3.7. A HandlerExceptionResolver Felület

Tavaszi HandlerExceptionResolver egységes hibakezelést biztosít egy teljes webalkalmazáshoz, egyetlen vezérlőhöz vagy vezérlőkészlethez.

Az alkalmazásszintű egyedi kivételkezelés biztosításához hozzon létre egy osztályt, amelyhez jegyzet van @ControllerAdvice:

@ControllerAdvice nyilvános osztály ExampleGlobalExceptionHandler {@ExceptionHandler @ResponseBody public String handleExampleException (e kivétel) {// ...}}

Az osztályon belüli bármelyik módszerrel annotálták @ExceptionHandler a diszpécser felelősségi körzetében minden ellenőrnél elérhetővé válik.

A HandlerExceptionResolver interfész a DispatcherServlet ApplicationContext állnak rendelkezésre elfog egy adott vezérlőt a diszpécser felelősségi körébe tartozik bármikor @ExceptionHandler kommentárként használják, és a helyes osztályt adja meg paraméterként:

@Controller public class FooController {@ExceptionHandler ({CustomException1.class, CustomException2.class}) public void handleException () {// ...} // ...}

A handleException () metódus most kivételkezelőként szolgál a FooController a fenti példánkban, ha bármelyik kivétel CustomException1 vagy CustomException2 bekövetkezik.

Itt van egy cikk, amely részletesebben bemutatja a Spring webes alkalmazás kivételkezelését.

4. Következtetés

Ebben az oktatóanyagban áttekintettük a tavaszit DispatcherServlet és a konfigurálásának több módja.

Mint mindig, az oktatóanyagban használt forráskód is elérhető a Githubon.