SpringBoot; filtreler, önleyiciler ve dilimler uygular

Filtrele

Filtre konsepti

Filtre, J2E'den alınmıştır ve Servlet'in "geliştirilmiş sürümü" olarak kabul edilebilir. Esas olarak kullanıcı isteklerini ön işleme ve sonradan işlemek için kullanılır ve tipik bir işleme zincirine sahiptir. Filtre ayrıca, Servlet ile aynı olan, kullanıcı isteklerine yanıtlar da oluşturabilir, ancak pratikte Filtre, kullanıcı isteklerine yanıt oluşturmak için nadiren kullanılır.

Filtre kullanmanın tam süreci şudur: Filtre, kullanıcı talebini önceden işler, ardından isteği ön işleme için Servlet'e iletir ve bir yanıt oluşturur ve son olarak Filter, sunucu yanıtını sonradan işler.

Filtre işlevi

Çeşitli filtrelerin işlevleri JavaDoc'ta verilmiştir.

Bu tasarım için belirlenmiş örnekler

1) Kimlik Doğrulama Filtreleri, yani kullanıcı erişim izinleri filtreleme

2) Günlük Kaydı ve Denetleme Filtreleri, günlük filtreleme, özel kullanıcıların özel isteklerini vb. Kaydedebilir.

3) Görüntü dönüştürme Filtreleri

4) Veri sıkıştırma Filtreleri

5) Şifreleme Filtreleri

6) Tokenleştirme Filtreleri

7) Kaynak erişim olaylarını tetikleyen filtreler

8) XSL / T filtreleri

9) Mime tipi zincir filtresi

İlk öğe için, yani izin filtreleme için Filtre kullanmak, şu şekilde uygulanabilir: Her bir istemci tarafından başlatılan istek URL'sini almak için bir Filtre tanımlayın ve bunu mevcut kullanıcının erişim iznine sahip olmadığı URL'lerin listesiyle karşılaştırın (DB'den alınabilir) , İzin filtreleme rolünü oynar.

Filtre uygulaması

Tüm özel filtreler javax.Servlet.Filter arayüzünü uygulamalı ve arayüzde tanımlanan üç yöntemi yeniden yazmalıdır:

1. init'ten kaçının (FilterConfig yapılandırması)

Filtrenin başlatılmasını tamamlamak için kullanılır.

2. yok etmekten kaçının ()

Filtre yok edilmeden önce belirli kaynakların kurtarılmasını tamamlamak için kullanılır.

3. doFilter'den kaçının (ServletRequest isteği, ServletResponse yanıtı, FilterChain zinciri)

Filtreleme işlevini, yani her istek ve yanıt için ek ön işleme ve son işlemeyi gerçekleştirin. , Bu yöntemi çalıştırmadan önce, kullanıcı talebi önceden işlenir; bu yöntemi uyguladıktan sonra, sunucu yanıtı sonradan işlenir.

Chain.doFilter () yönteminin ön işleme aşamasından önce yürütüldüğüne dikkat etmek önemlidir.Yöntem çalıştırmanın sonu, kullanıcının isteğinin denetleyici tarafından işlendiği anlamına gelir. Bu nedenle, doFilter'da chain.doFilter () yöntemini çağırmayı unutursanız, kullanıcının isteği işlenmeyecektir.

importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.stereotype.Component; importjavax.servlet. *; importjavax.servlet.http.HttpServletRequest; importjava.io.IOException; // Web üzerinden bir yorum eklemelisiniz. xml yapılandırması @ComponentpublicclassTimeFilterimplementsFilter {privatestaticfinalLoggerLOG = LoggerFactory.getLogger (TimeFilter.class); @ Overridepublicvoidinit (FilterConfigfilterConfig) throwsServletException {LOG.info ("İlk filtrelemeFiltresi: {}", Overridepublicvoidinit); , FilterChainchain) throwsIOException, ServletException {LOG.info ("starttodoFilter"); longstartTime = System.currentTimeMillis (); chain.doFilter (istek, yanıt); longendTime = System.currentTimeMillis (); LOG.info ("therequestof {} tüketir {} ms. ", getUrlFrom (istek), (endTime-startTime)); LOG.info (" endtodoFilter ");} @ Overridepublicvoiddestroy () {LOG.info (" Destroy filter ");} privateStringgetUrlFrom (ServletRequestservletRequest) { eğer (servletRequestinstanceofHttpServletRequest) {return ((HttpSe rvletRequest) servletRequest) .getRequestURL (). toString ();} return "";}}

Filtre sınıfının javax.servlet. * İçinde olduğu koddan görülebilir, bu nedenle filtrenin büyük bir sınırlamasının mevcut kullanıcı isteğinin hangi denetleyici (Denetleyici) olduğunu bilememesi olduğu görülebilir. İşleme, çünkü ikincisi yay çerçevesinde tanımlanır.

SpringBoot'ta bir üçüncü taraf filtresi kaydedin

SpringMvc için filtreyi web.xml dosyasında kaydedebilirsiniz. Ancak, SpringBoot'ta web.xml yoktur. Şu anda, bir jar paketindeki bir filtreye başvurulursa ve filtre @Component tarafından Spring Bean olarak tanımlanmazsa, filtre etkili olmayacaktır.

Şu anda, filtreyi java kodu aracılığıyla kaydetmeniz gerekir. Örnek olarak yukarıda tanımlanan TimeFilter'ı ele alalım, @Component sınıf ek açıklaması kaldırıldığında kayıt yöntemi:

@ConfigurationpublicclassWebConfig {/ *** Bir üçüncü taraf filtresi kaydedin * İşlev, web.xml*@return * / @ BeanpublicFilterRegistrationBeanthirdFilter () {ThirdPartFilterthirdPartFilter = newThirdPeanfilterset (); FilterReanReanFilter (); filtresini yapılandırarak springmvc'deki ile aynıdır. );Liste < Dize > urls = newArrayList < > (); // Tüm istek yollarını eşleştir urls.add ("/ *"); filterRegistrationBean.setUrlPatterns (urls); returnfilterRegistrationBean;}}

@Component ek açıklaması ile karşılaştırıldığında, bu yapılandırma yönteminin bir avantajı vardır, yani yakalanan URL serbestçe yapılandırılabilir.

Interceptor

Önleyici kavramı

Interceptor, AOP'de (Görünüş Odaklı Programlama) bir yöntemi veya alanı erişilmeden önce durdurmak ve ardından belirli işlemleri öncesine veya sonrasına eklemek için kullanılır. Durdurma, AOP'nin bir uygulama stratejisidir.

Interceptor rolü

  • Günlük kaydı: Bilgi izleme, bilgi istatistikleri, PV (Sayfa Görünümü) hesaplaması vb. İçin istenen bilgi günlüğünü kaydedin.
  • İzin kontrolü: Giriş algılama gibi, giriş yapılıp yapılmayacağını tespit etmek için işlemciye girin
  • Performans izleme: Önleyen, işlemciye girmeden önceki başlangıç zamanını kaydeder ve işlemeden sonraki bitiş zamanını kaydeder, böylece talebin işleme süresini elde eder. (Apache gibi ters proxy de otomatik olarak kayıt yapabilir);
  • Genel davranış: Kullanıcı bilgilerini almak ve kullanıcı nesnesini talebe eklemek için çerezi okuyun, böylece sonraki işlem kullanımını kolaylaştırmak ve Yerel Ayar, Tema bilgileri vb. Ayıklayın, birden çok işlemcinin ihtiyaç duyduğu sürece, elde etmek için durdurucuyu kullanabilirsiniz.

Interceptor uygulaması

HandlerInterceptor arabirimini uygulayarak ve arabirimin üç yöntemini yeniden yazarak durdurucuyu özelleştirin:

1.preHandler (HttpServletRequest isteği, HttpServletResponse yanıtı, Nesne işleyicisi)

Yöntem, talep işlenmeden önce çağrılacaktır. SpringMVC'deki Interceptor, zincir çağrısındaki Filter ile aynıdır. Her Interceptor çağrısı, bildirim sırasına göre sırayla yürütülecektir ve ilk çalıştırılacak olan Interceptor'daki preHandle yöntemidir, bu nedenle bazı ön başlatma işlemleri veya mevcut talebin bir ön işlemi bu yöntemde gerçekleştirilebilir. Talebin devam edip etmeyeceğine karar vermek için bu yöntemde bazı yargılarda bulunabilirsiniz.

Bu yöntemin dönüş değeri Boolean tipindedir.Yanlış döndürdüğünde, isteğin bittiğini ve ardından Interceptor ve Controller'ın çalıştırılmayacağını; dönüş değeri true olduğunda, bir sonraki Interceptor'ın preHandle yöntemi çağrılmaya devam edilecektir. , Son Durdurucu ise, şu anda talep edilen Denetleyici yöntemini çağıracaktır.

2.postHandler (HttpServletRequest isteği, HttpServletResponse yanıtı, Nesne işleyicisi, ModelAndView modelAndView)

Geçerli istek işlendikten sonra, Controller yöntemi çağrıldıktan sonra yürütülür, ancak DispatcherServlet görünüm dönüşü işlemesini gerçekleştirmeden önce çağrılır, böylece Controller bu yöntemde işlendikten sonra ModelAndView nesnesi üzerinde işlem yapabiliriz.

3.afterCompletion (HttpServletRequest isteği, HttpServletResponse yanıtı, Nesne tutamacı, Exception ex)

Bu yöntemin, karşılık gelen Interceptor'ın preHandle yönteminin dönüş değeri doğru olduğunda da yürütülmesi gerekir. Adından da anlaşılacağı gibi, bu yöntem tüm istek sona erdikten sonra, yani DispatcherServlet ilgili görünümü oluşturduktan sonra çalıştırılacaktır. Bu yöntemin ana işlevi kaynakları temizlemektir.

@ComponentpublicclassTimeInterceptorimplementsHandlerInterceptor {privatestaticfinalLoggerLOG = LoggerFactory.getLogger (TimeInterceptor.class); @ OverridepublicbooleanpreHandle (HttpServletRequestrequest (HttpServletRequest), "Objeyi işlemeden önce HttpServletRequest" "," HttpServletResponsCecception "isteği startTime ", System.currentTimeMillis ()); HandlerMethodhandlerMethod = (HandlerMethod) işleyici; LOG.info (" controllerobjectis {} ", handlerMethod.getBean (). getClass (). getName ()); LOG.info (" controllermethodis {} ' Ancak, görünüm oluşturulmadan önce (Controller yöntemi çağrıldıktan sonra), bir istisna meydana gelirse, yöntem çağrılmaz ");} @ OverridepublicvoidafterCompletion (HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex) isteğin tamamında (" İsteğin tamamında "LOG.info özel durumu) atar Daha sonra çağrılır, yani DispatcherServlet ilgili görünümü oluşturduktan sonra çalıştırılır (esas olarak kaynak temizliği için) "); longs tartTime = (long) request.getAttribute ("startTime"); LOG.info ("timeconsumeis {}", System.currentTimeMillis () - startTime);}

Filtreden farklı olarak, engelleyici @Component ile dekore edildikten sonra, WebMvcConfigurer uygulanarak SpringBoot'a manuel olarak kaydedilmesi gerekir:

// java yapılandırma sınıfı @ ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer {@AutowiredprivateTimeInterceptortimeInterceptor; @OverridepublicvoidaddInterceptors (InterceptorRegistryregistry) {registry.addInterceptor (timeInterceptor);}}

SpringMVC'de ise, xml dosyası aracılığıyla yapılandırmanız gerekir < mvc: engelleyiciler > Düğüm bilgileri.

Dilim Boyutu

Dilimlemeye genel bakış

Filtrelerle karşılaştırıldığında, engelleyici, kullanıcı tarafından gönderilen talebin nihai olarak hangi denetleyici tarafından işlendiğini bilebilir, ancak önleyicinin bariz bir kusuru vardır, yani, isteğin parametrelerini ve denetleyici işledikten sonra yanıtı elde edemez. Yani dilimlemek için bir yer var.

Dilim uygulaması

Dilimleme uygulamasında, @Aspect, @Component ve @Around olmak üzere üç ek açıklamanın kullanımına dikkat edilmelidir. Ayrıntılar için resmi belgeleri kontrol edin:

https://docs.spring.io/spring/docs/5.0.12.RELEASE/spring-framework-reference/core.html#aop

@ Aspect @ ComponentpublicclassTimeAspect {privatestaticfinalLoggerLOG = LoggerFactory.getLogger (TimeAspect.class); @ Around ("execution (* me.ifight.controller. *. * (..)") publicObjecthandleControllerMethod (ProceedingJoinPoint) (ProceedingJoinPoint) Dilim başlangıcı ... "); longstartTime = System.currentTimeMillis (); // İstek girdisini al Objectargs = progressingJoinPoint.getArgs (); Arrays.stream (args) .forEach (arg- > LOG.info ("argis {}", arg)); // İlgili Objectresponse = progressingJoinPoint.proceed (); longendTime = System.currentTimeMillis (); LOG.info ("İstek: {}, zaman alan {} ms" , progressingJoinPoint.getSignature (), (endTime-startTime)); LOG.info ("Dilimin sonu ..."); returnnull;}}

Filtrelerin, engelleyicilerin ve dilimlerin çağrı sırası

Aşağıdaki şekil, üç Filtrenin arama sırasını göstermektedir. > Intercepto- > Görünüş- > Denetleyici. Aksine, Kontrolör tarafından atılan istisnaların işleme sırası içeriden dışarıya doğrudur. Bu nedenle, denetleyici tarafından oluşturulan istisnaları tek tip olarak işlemek için her zaman bir @ControllerAdvice ek açıklaması tanımlarız.

İstisna @ControllerAdvice tarafından işlenirse, çağrı durdurucunun afterCompletion yönteminin Exception istisnası parametresi boş olacaktır.

Çağrı yığınının gerçek uygulaması da bu noktayı göstermektedir:

Filtreler ve önleyiciler için ayrıntılı arama sırası aşağıdaki gibidir:

Filtreler ve önleyiciler arasındaki fark

Son olarak, filtreler ve önleyiciler arasındaki farktan bahsetmek gerekir:

Ek olarak, filtrelerle karşılaştırıldığında, önleyiciler kullanıcının isteğini Spring çerçevesinin hangi denetleyicisinin işlediğini "görebilir".

Bir dizi temel otomatik dağıtım ve inşa süreci
önceki
Zhou Yutong'un sık sık görünüşü yükseldi! Küçük yeşil bir takım elbise giymek bir erkek çocuktan daha yakışıklı, gerçekten kıyaslanamaz
Sonraki
Song Yanfei'nin tatil yeri tarzı giyinmesi nefreti çekiyor! Tropiklerde böyle giyiyoruz, üşüyoruz
En yeni Japon sanatçı Yuko Shinki'nin en son özel sunucusu, yumuşak ve sevimli tarzı çok hoş ve model popüler.
Şımarık ve sıcak katmanlı kıyafetler 2020 bahar sezonu için hazır, sadece gökyüzünün açılmasını bekleyin
Jin Zhini, aylık W2 dergisinin Kore versiyonunun kapağındaydı, ancak etli yüzünün bu kadar kız gibi olmasını beklemiyordu.
Park Caiying'in sarı saçları ana akım değil mi? Ne kadar saf bir Koreli kadın sanatçı, bu ana akım maç
Zhou Dongyu "kırmızı kumaştan" bir şerit sararak Bahar Şenliği Galasına gitti. Bu yaramaz küçük kırmızı ördeğin kırmızı kutsamaları var. Gerçekten şenlikli
Zheng Shuang ve ailesi aynı sahnede sevimli şarkı söylediler. Bu yakışıklı babanın çıkış yapmaması üzücü ve annesi de son derece güzel
Angelababy, Pekin'deki Bahar Şenliği Galasında göründü, tüp üst etek düşmek üzere ve batı kıyafetleri çok havalı
Tong Liya büyüleyici kadınların temsilcisi olmaya değer. 3 set CCTV Bahar Şenliği Gala stilleri aşırı değil
Tao Hong 48 yaşında ve seksi oynamaya cesaret ediyor! Küçük çiğ omuzlar, yarı güzel bacaklar, bu kadınsı
O Suinin yeni yılın istifleme kuralları gerçekten keskin ve sonra büyük bir rüzgar kırıcı takıyor, aura saniyeler içinde kazanıyor, süper model olmayı hak ediyor
Küf ender bir fotoğraf çekimi. Sarı ve kırmızı dudaklar hala ikonik bir eşleşme. Sence güzel koktu mu?
To Top