Introduktion til Spring MVC HandlerInterceptor
1. Introduktion
I denne vejledning fokuserer vi på at forstå Spring MVC HandlerInterceptor og hvordan man bruger det korrekt. For at forstå interceptor, lad os tage et skridt tilbage og se på HandlerMapping. Dette kortlægger en metode til en URL, således at DispatcherServlet vil være i stand til at påberåbe sig det, når man behandler en anmodning. Og DispatcherServlet bruger Handler-adapter for faktisk at påberåbe sig metoden. Nu hvor vi forstår den overordnede kontekst - det er her, der handler interceptor kommer ind. Vi bruger HandlerInterceptor at udføre handlinger inden håndtering, efter håndtering eller efter afslutning (når visningen gengives) af en anmodning. Interceptoren kan bruges til tværgående bekymringer og for at undgå gentagne handlingskoder som logning, ændring af globalt anvendte parametre i Spring-model osv. I de næste par sektioner er det præcis, hvad vi skal se på - forskellene mellem forskellige interceptorimplementeringer. For at bruge Opfangere, skal du medtage følgende afsnit i a afhængigheder sektion af din pom.xml fil: Den seneste version kan findes her. Opfangere, der arbejder med HandlerMapping på rammen skal gennemføre HandlerInterceptor interface. Denne grænseflade indeholder tre hovedmetoder: Disse tre metoder giver fleksibilitet til at udføre alle former for for- og efterbehandling. Og en hurtig note - den største forskel mellem HandlerInterceptor og HandlerInterceptorAdapter er, at i den første skal vi tilsidesætte alle tre metoder: preHandle (), postHandle () og afterCompletion (), mens vi i det andet kun implementerer nødvendige metoder. En hurtig note, inden vi går videre - hvis du vil springe over teorien og springe direkte til eksempler, skal du hoppe lige ind i afsnit 5. Her er hvad en simpel preHandle () implementering vil se ud: Bemærk, at metoden returnerer a boolsk værdi - som fortæller Spring, om anmodningen skal behandles yderligere af en handler (rigtigt) eller ikke (falsk). Dernæst har vi en implementering af postHandle (): Denne metode kaldes straks efter anmodningen er behandlet af Handler-adapter, men inden du genererer en visning. Og det kan selvfølgelig bruges på mange måder - for eksempel kan vi tilføje en avatar fra en logget bruger i en model. Den sidste metode, vi skal implementere i skikken HandlerInterceptor implementering er afterCompletion (): Når visningen er genereret, kan vi bruge denne krog til at gøre ting som at indsamle yderligere statistik relateret til anmodningen. En sidste note at huske er, at en HandlerInterceptor er registreret til StandardAnnotationHandlerMapping bean, som er ansvarlig for at anvende interceptors på enhver klasse markeret med a @Kontrol kommentar. Desuden kan du angive et hvilket som helst antal interceptors i din webapplikation. I dette eksempel vil vi fokusere på logning i vores webapplikation. Først og fremmest skal vores klasse udvides HandlerInterceptorAdapter: Vi skal også aktivere logning i vores interceptor: Dette gør det muligt for Log4J at vise logfiler samt angive, hvilken klasse der i øjeblikket logger information til den specificerede output. Lad os derefter fokusere på tilpassede interceptorimplementeringer: Denne metode kaldes inden behandling af en anmodning; det vender tilbage rigtigt, at tillade rammen at sende anmodningen videre til behandlingsmetoden (eller til den næste interceptor). Hvis metoden vender tilbage falskSpring antager, at anmodningen er blevet håndteret, og der er ikke behov for yderligere behandling. Vi kan bruge krogen til at logge information om anmodningernes parametre: hvor anmodningen kommer fra osv. I vores eksempel logger vi denne info ved hjælp af en simpel Log4J-logger: Som vi kan se, logger vi nogle grundlæggende oplysninger om anmodningen. I tilfælde af at vi løber ind i en adgangskode her, skal vi selvfølgelig ikke logge det. En enkel mulighed er at erstatte adgangskoder og enhver anden følsom type data med stjerner. Her er en hurtig implementering af, hvordan det kan gøres: Endelig sigter vi mod at få kilde-IP-adressen til HTTP-anmodningen. Her er en simpel implementering: Denne krog kører, når Handler-adapter påberåbes handler men DispatcherServlet er endnu ikke til at gengive udsigten. Vi kan bruge denne metode til at tilføje yderligere attributter til ModelAndView eller at bestemme, hvor lang tid det tager med behandlingsmetoden at behandle en klients anmodning. I vores tilfælde logger vi simpelthen en anmodning lige før DispatcherServlet kommer til at gengive en visning. Når en anmodning er færdig, og visningen gengives, kan vi indhente anmodnings- og svardata samt oplysninger om undtagelser, hvis der opstod: For at tilføje vores interceptors i Spring-konfiguration er vi nødt til at tilsidesætte addInterceptors () metode indeni WebConfig klasse, der implementerer WebMvcConfigurer: Vi opnår muligvis den samme konfiguration ved at redigere vores XML Spring-konfigurationsfil: Når denne konfiguration er aktiv, vil interceptoren være aktiv, og alle anmodninger i applikationen vil blive logget korrekt. Bemærk, at hvis der er konfigureret flere fjederinterceptorer, skal preHandle () metoden udføres i rækkefølgen af konfigurationen, mens postHandle () og afterCompletion () metoder påberåbes i omvendt rækkefølge. Hvis vi bruger Spring Boot i stedet for vanilla Spring, skal vi huske på ikke at kommentere vores konfigurationsklasse med @EnableWebMvc, ellers mister vi Boot's automatiske konfigurationer. Denne vejledning er en hurtig introduktion til at opfange HTTP-anmodninger ved hjælp af Spring MVC Handler Interceptor. Alle eksempler og konfigurationer er tilgængelige her på GitHub.2. Fjeder MVC-håndterer
3. Maven-afhængigheder
org.springframework spring-web 5.2.8.RELEASE
4. Spring Handler Interceptor
@Override offentlig boolsk preHandle (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler) kaster Undtagelse {// din kode returnerer sand; }
@Override public void postHandle (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler, ModelAndView modelAndView) kaster Undtagelse {// din kode}
@Override public void afterCompletion (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler, Undtagelse ex) {// din kode}
5. Custom Logger Interceptor
public class LoggerInterceptor udvider HandlerInterceptorAdapter {...}
privat statisk loggerlog = LoggerFactory.getLogger (LoggerInterceptor.class);
5.1. Metode preHandle ()
@Override offentlig boolsk preHandle (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler) kaster undtagelse {log.info ("[preHandle] [" + anmodning + "]" + "[" + request.getMethod () + "]" + anmodning .getRequestURI () + getParameters (anmodning)); returner sandt; }
private String getParameters (HttpServletRequest anmodning) {StringBuffer sendt = ny StringBuffer (); Optælling e = request.getParameterNames (); hvis (e! = null) {posted.append ("?"); } mens (e.hasMoreElements ()) {if (posted.length ()> 1) {posted.append ("&"); } String curr = (String) e.nextElement (); posted.append (curr + "="); hvis (curr.contains ("password") || curr.contains ("pass") || curr.contains ("pwd")) {posted.append ("*****"); } andet {posted.append (request.getParameter (curr)); }} String ip = request.getHeader ("X-FORWARDED-FOR"); String ipAddr = (ip == null)? getRemoteAddr (anmodning): ip; hvis (ipAddr! = null &&! ipAddr.equals ("")) {posted.append ("& _ psip =" + ipAddr); } returneret. toString (); }
private String getRemoteAddr (HttpServletRequest anmodning) {String ipFromHeader = request.getHeader ("X-FORWARDED-FOR"); hvis (ipFromHeader! = null && ipFromHeader.length ()> 0) {log.debug ("ip fra proxy - X-FORWARDED-FOR:" + ipFromHeader); returner ipFromHeader; } returner anmodning.getRemoteAddr (); }
5.2. Metode postHandle ()
@ Overstyr offentlig ugyldig postHandle (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler, ModelAndView modelAndView) kaster Undtagelse {log.info ("[postHandle] [" + anmodning + "]"); }
5.3. Metode afterCompletion ()
@Override public void afterCompletion (HttpServletRequest anmodning, HttpServletResponse svar, Objektbehandler, Exception ex) kaster Exception {if (ex! = Null) {ex.printStackTrace (); } log.info ("[afterCompletion] [" + anmodning + "] [undtagelse:" + ex + "]"); }
6. Konfiguration
@Override offentlige ugyldige addInterceptors (InterceptorRegistry registry) {registry.addInterceptor (ny LoggerInterceptor ()); }
7. Konklusion