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:
- 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
- az utótaggal beállított alapértelmezett nézettípus
- 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: 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: 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: Most, hogy konfiguráltuk MultipartResolver bab, állítsunk be egy vezérlőt a feldolgozáshoz MultipartFile kérések: 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. 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: 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: 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. 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.@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 ()); }
//localhost:8080/dispatcherexample-1.0.0/?theme=example
3.6. A MultipartResolver Felület
@Bean public CommonsMultipartResolver multipartResolver () dobja az IOException-t {CommonsMultipartResolver resolver = new CommonsMultipartResolver (); resolver.setMaxUploadSize (10000000); return resolver; }
@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; }}
3.7. A HandlerExceptionResolver Felület
@ControllerAdvice nyilvános osztály ExampleGlobalExceptionHandler {@ExceptionHandler @ResponseBody public String handleExampleException (e kivétel) {// ...}}
@Controller public class FooController {@ExceptionHandler ({CustomException1.class, CustomException2.class}) public void handleException () {// ...} // ...}
4. Következtetés