Bevezetés a Spring MVC HandlerInterceptor-ba
1. Bemutatkozás
Ebben az oktatóanyagban a tavaszi MVC megértésére koncentrálunk HandlerInterceptor és hogyan kell helyesen használni. Az elfogó megértése érdekében tegyünk egy lépést hátra, és nézzük meg a HandlerMapping. Ez leképezi a metódust egy URL-re, így a DispatcherServlet kérés feldolgozása során hivatkozhat rá. És a DispatcherServlet használja a HandlerAdapter hogy ténylegesen meghívják a módszert. Most, hogy megértettük az általános kontextust - itt jön be a kezelő elfogó. Használjuk a HandlerInterceptor műveletek végrehajtása a kérelem kezelése, kezelése vagy befejezése után (amikor a nézet megjelenik). Az elfogó használható keresztmetszeti problémákra és az ismétlődő kezelői kód elkerülésére, mint például naplózás, a globálisan használt paraméterek megváltoztatása a Spring modellben stb. A következő néhány szakaszban pontosan ezt fogjuk vizsgálni - a különböző elfogó megvalósítások közötti különbségek. Használata érdekében Elfogók, be kell foglalnia a következő szakaszt a függőségek szakasza pom.xml fájl: A legújabb verzió itt található. A HandlerMapping keretrendszeren kell végrehajtania a HandlerInterceptor felület. Ez a felület három fő módszert tartalmaz: Ez a három módszer rugalmasságot biztosít mindenféle elő- és utófeldolgozáshoz. És egy gyors megjegyzés - a fő különbség HandlerInterceptor és HandlerInterceptorAdapter az, hogy az elsőben felül kell írnunk mindhárom módszert: preHandle (), postHandle () és afterCompletion (), míg a másodikban csak a szükséges módszereket valósíthatjuk meg. Egy gyors megjegyzés, mielőtt továbbmennénk - ha át akarja hagyni az elméletet és egyenesen a példákra mutat, ugorjon közvetlenül az 5. szakaszba. Itt egy egyszerű preHandle () a megvalósítás így fog kinézni: Figyelje meg, hogy a metódus a logikai érték - amely megmondja Springnek, hogy a kérést egy kezelőnek tovább kell-e dolgoznia (igaz) vagy nem (hamis). Ezután megvalósítjuk a postHandle (): Ezt a módszert azonnal meghívják, miután a kérelmet feldolgozta HandlerAdapter, de mielőtt nézetet generálna. És természetesen sokféleképpen használható - például hozzáadhatunk egy modellbe egy bejelentkezett felhasználó avatárját. A végső módszer, amelyet a szokás szerint kell végrehajtanunk HandlerInterceptor megvalósítás az afterCompletion (): Ha a nézet sikeresen elkészült, akkor ezt a horgot felhasználhatjuk például a kéréssel kapcsolatos további statisztikák gyűjtésére. Az utolsó emlékezetes megjegyzés, hogy a HandlerInterceptor be van jegyezve a DefaultAnnotationHandlerMapping bab, amely feladata az elfogók alkalmazása az a betűvel jelölt osztályokba @Vezérlő annotáció. Ezenkívül tetszőleges számú elfogót határozhat meg webes alkalmazásában. Ebben a példában a naplózásra fogunk összpontosítani webes alkalmazásunkban. Először is, osztályunknak bővülnie kell HandlerInterceptorAdapter: Engedélyeznünk kell a naplózást az elfogónkban is: Ez lehetővé teszi a Log4J számára a naplók megjelenítését, valamint annak jelzését, hogy melyik osztály naplózza az információkat a megadott kimenethez. Ezután összpontosítsunk az egyedi elfogók megvalósítására: Ezt a módszert a kérelem kezelése előtt hívják meg; visszatér igaz, hogy a keretrendszer tovább tudja küldeni a kérést a kezelő metódusnak (vagy a következő elfogónak). Ha a metódus visszatér hamis, Spring feltételezi, hogy a kérelmet elbírálták, és nincs szükség további feldolgozásra. A horog segítségével naplózhatunk információkat a kérések paramétereiről: honnan származik a kérés stb. Példánkban ezeket az információkat egy egyszerű Log4J naplózóval naplózzuk: Mint láthatjuk, naplózunk néhány alapvető információt a kérelemről. Abban az esetben, ha belefutunk egy jelszóba, akkor természetesen meg kell győződnünk arról, hogy nem naplózunk. Egyszerű lehetőség a jelszavak és minden más érzékeny adattípus helyettesítése csillagokkal. Az alábbiakban bemutatjuk, hogyan lehet ezt megtenni: Végül arra törekszünk, hogy megkapjuk a HTTP kérés forrás IP címét. Itt van egy egyszerű megvalósítás: Ez a horog akkor fut, amikor a HandlerAdapter hívják a kezelőt, de DispatcherServlet még meg kell adnia a nézetet. Ezzel a módszerrel további attribútumokat adhatunk a ModelAndView vagy az ügyfél kérésének feldolgozásához szükséges idő meghatározása kezelő módszerrel. Esetünkben egyszerűen naplózunk egy kérést közvetlenül azelőtt DispatcherServlet nézetet fog megjeleníteni. Amikor egy kérés befejeződik és a nézet megjelenik, kérés- és válaszadatokat, valamint információkat kaphatunk a kivételekről, ha történtek ilyenek: Ha elfogóinkat hozzá akarjuk adni a Spring konfigurációhoz, felül kell írnunk addInterceptors () módszer belül WebConfig osztály, amely megvalósítja WebMvcConfigurer: Ugyanezt a konfigurációt érhetjük el az XML Spring konfigurációs fájlunk szerkesztésével: Ha ez a konfiguráció aktív, akkor az elfogó aktív lesz, és az alkalmazás összes kérését megfelelően naplózza. Kérjük, vegye figyelembe, hogy ha több rugós elfogó van beállítva, akkor a preHandle () metódust a konfiguráció sorrendjében hajtjuk végre, míg postHandle () és afterCompletion () a módszereket fordított sorrendben hívják meg. Ha a vanília tavasz helyett Spring Bootot használunk, ne felejtsük el, hogy nem jelöljük meg a konfigurációs osztályunkat @EnableWebMvc, különben elveszítjük a Boot automatikus konfigurációit. Ez az oktatóanyag bemutatja a HTTP kérések elfogását a Spring MVC Handler Interceptor segítségével. Minden példa és konfiguráció itt érhető el a GitHub-on.2. Tavaszi MVC kezelő
3. Maven-függőségek
org.springframework spring-web 5.2.8.FELHASZNÁLÁS
4. Spring Handler Interceptor
@Orride public boolean preHandle (HttpServletRequest kérés, HttpServletResponse válasz, Objektumkezelő) dobja a Kivételt {// a kód visszatér true; }
@Override public void postHandle (HttpServletRequest kérés, HttpServletResponse válasz, Objektumkezelő, ModelAndView modelAndView) dobja a Kivételt {// kódod}
@Orride public void afterCompletion (HttpServletRequest kérés, HttpServletResponse válasz, Objektumkezelő, Kivétel ex) {// kódod}
5. Custom Logger Interceptor
A nyilvános osztályú LoggerInterceptor kiterjeszti a HandlerInterceptorAdapter {...}
privát statikus naplózó napló = LoggerFactory.getLogger (LoggerInterceptor.class);
5.1. Módszer preHandle ()
@Orride public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) dobja a {Log.info ("[preHandle] [" + request + "]" + "[" + request.getMethod () + "]" + kivétel kérelmet .getRequestURI () + getParameters (kérés)); return true; }
privát karakterlánc getParameters (HttpServletRequest kérés) {StringBuffer kiküldött = new StringBuffer (); Számlálás e = request.getParameterNames (); if (e! = null) {kiküldött.append ("?"); } while (e.hasMoreElements ()) {if (posted.length ()> 1) {posted.append ("&"); } String curr = (String) e.nextElement (); posted.append (curr + "="); if (curr.contains ("jelszó") || curr.contains ("pass") || curr.contains ("pwd")) {posted.append ("*****"); } else {posted.append (request.getParameter (valuta)); }} String ip = request.getHeader ("X-FORWARDED-FOR"); Karakterlánc ipAddr = (ip == null)? getRemoteAddr (kérés): ip; if (ipAddr! = null &&! ipAddr.equals ("")) {posted.append ("& _ psip =" + ipAddr); } return posted.toString (); }
privát karakterlánc getRemoteAddr (HttpServletRequest kérés) {String ipFromHeader = request.getHeader ("X-FORWARDED-FOR"); if (ipFromHeader! = null && ipFromHeader.length ()> 0) {log.debug ("ip proxyból - X-FORWARDED-FOR:" + ipFromHeader); return ipFromHeader; } return request.getRemoteAddr (); }
5.2. Módszer postHandle ()
@Override public void postHandle (HttpServletRequest kérés, HttpServletResponse válasz, Objektumkezelő, ModelAndView modelAndView) dobja a {Log.info ("[postHandle] [" + kérelem + "]") kivételt; }
5.3. Módszer afterCompletion ()
@Override public void afterCompletion (HttpServletRequest kérés, HttpServletResponse válasz, Objektumkezelő, Kivétel ex) dobja a Kivételt {if (ex! = Null) {ex.printStackTrace (); } log.info ("[afterCompletion] [" + kérés + "] [kivétel:" + ex + "]"); }
6. Konfiguráció
@Orride public void addInterceptors (InterceptorRegistry registry) {register.addInterceptor (új LoggerInterceptor ()); }
7. Következtetés