Bilal Koçoğlu/ Aralık 13, 2018/ Servlet

 Servlet Filter

Filter, bir requestin preprosessing(önişleme) ve postprosessiong zamanında çağrılır. Bu kavramları kısaca açıklamak gerekirse; preprosessing(önişleme), işlemcide(CPU) çalışmadan önce yapılacak işleri ifade etmek için kullanılır. Postprosessing ise bunun tam tersi, yani tüm işlemler gerçekleştikten sonra yapılacak işleri ifade etmek için kullanılan bir terimdir.

Peki bu postprosessing ve preprosessing bize hangi işlemleri gerçekleştirmek istediğimizde yardımcı olur ? Bu iki işlem zamanını dönüşüm(conversion), logging(kayıt tutma), şifreleme(encryption) ve şifre çözme(decryption), girdi doğrulama vb. filtreleme görevlerini yerine getirmek için kullanabiliriz. Bahsettiğim işlemlerin sadece bir kavramdan ibaret olmadığına ve projelerimizde ne derece faydalı olabileceğine dikkat çekmek için birkaç örnek senaryo ile filtrelerin önemini anlayalım. 

Filter
Filter

 Projelerimizde bazen controllerlarımıza gelen requestlerde parametre tip dönüşümleri, erişim veya yetkilendirme parametrelerinin kontrol edilmesi gibi işlemleri yapmak isteriz. Böyle bir durumda filtre kullanarak preprosessing sayesinde istediğimiz işlemleri yapar, sonrasında controllera ulaşmasına izin veririz. Aynı şekilde ortaya istatistiksel bir veri çıkarmak istediğimizde veya yönetici tarafından kontrol edilebilirliğin sağlanması açısından gelen requestlerin bazı özelliklerini kayıt altına almak isteyebiliriz. Bu durumda da filter bizim için büyük bir kolaylık olacaktır. Sistemimizin güvenliği açısından örnek olarak kullanıcı girişinde veya kullanıcılar arası mesajlaşmada bazı parametrelerin şifreli şekilde controllera gelmesini isteyebiliriz. Bunlar ve daha nice benzeri problemlerde filter bizi çözüme ulaştıracak bir araç olabilir. 

Filtreler ile ilgili bir diğer önemli konuda bakım maliyetlerini oldukça düşürmesidir. Burada maliyetten kastım biz yazılımcılar için bulunmaz bir nimet olan zaman. Örneğin, yukarıda bahsettiğim gibi gelen request parametrelerinden bazılarını şifrelemek gerekti fakat siz bunu filter kullanmadan controllerlar içinde yapmayı tercih ettiniz. Daha sonra şifrelemek için kullandığınız algoritmayı değiştirme veya tamamen şifrelemeyi kaldırma kararı alındı. Bu tip durumlarda filter kullanmış olsaydınız muhtemelen 5 – 10 satır kod güncelleyerek problemi çözecektiniz fakat kullanmadığınız için tüm controller sınıflarında güncellenecek kısmı arayıp tek tek değişiklik yapmak zorunda kaldınız. Burada kaybettiğiniz zaman projenin boyutuyla orantılı bir şekilde katlanarak artacaktır. Elbette bunu istemeyiz. 

Servletlerin aksine bir filtrenin, başka bir filtreye bağımlılığı yoktur.

Son olarak filtre kullanabileceğimiz çeşitli durumları maddeler halinde sıralamak istiyorum;

  • Gelen tüm istekleri kaydetme(logging)
  • İstekte bulunan bilgisayarların ip adreslerini kaydetme
  • Dönüştürme
  • Veri sıkıştırma
  • Şifreleme ve şifre çözme
  • Girdi doğrulama(validation) vs.

Filter API

Servlet’te Filter’ın kendi API’si mevcuttur. Javax.servlet paketi, Filtre API’sinin üç arabirimini(interface) içerir. Bu arabirimler;

  • Filter
  • FilterChain
  • FilterConfig

Filter(Interface)

Özel bir filtre oluşturabilmek için bu arabirimi implements etmemiz gerekir. Filter interface, bir filtrenin yaşam döngünü yönetimini sağlar. Bu interface içinde override etmemiz gereken methodlar;

  • public void init(FilterConfig config) : Bu method sadece bir kez çağrılır ve filtreyi başlatmak için kullanılır.
  • public void doFilter(HttpServletRequest req, HttpServletResponse res) : Bu method, filtrenin eşleştirildiği herhangi bir controllar’a gelen her request için çağrılır. Filtreleme görevini yapmak için kullanılır. Yani filtre içinde asıl yapmak istediğimiz işlemleri bu methodda yazacağız.
  • public void destroy() : Bu method, filtrenin servisten çıkarıldığı(sonlandırıldığı) zaman yalnızca bir kere çalıştırılır.

FilterChain(Interface)

FilterChain nesnesi, zincirdeki bir sonraki filtreyi veya kaynağı çağırmakla yükümlüdür. Bu nesne Filter arayüzünün doFilter yönteminde geçirilir. FilterChain arabirimi yalnızca bir yöntem içerir:

  • public void doFilter(HttpServletRequest req, HttpServletResponse res) : Kontrolü bir sonraki filtreye veya kaynağa geçirir.

Şimdi bir örnek üzerinde konuyu pekiştirelim. Bu dersteki örneğimizde filter ile yukarıda bahsettiğimiz işlemlerden ziyade çalışma mantığını daha yakından inceleyip pekiştireceğiz. Servlet konusunun son dersinde filter ile giriş doğrulama işlemi yapılacaktır.

Dosya Yapısı
Filter
Filter in Servlet
pom.xml
index.jsp
HomeServlet.java
CustomFilter.java

Örnek üzerinden bazı kısımları inceleyelim. Dikkat ettiğiniz üzere web.xml dosyasını paylaşmadık bunun sebebi Filter ve Servlet üzerindeki @WebFilter ve @WebServlet anotasyonlarıdır. Bunlar sayesinde web.xml ‘de çeşitli etiketlerle yapacağımız işi tek satırda halledebiliyoruz. 

Diğer değinilmesi gereken bir nokta ise, oluşturduğumuz Servlet ve Filtreye aynı urlPattern’i atamamızdır. Bu şekilde Filter ile Servleti birbirine bağlamış oluyoruz. Bunun anlamı oluşturulan filtre sadece eşleşen servet’e bir request geldiğinde çalışacaktır. Eğer bir servlet daha oluştursaydık farklı urlPattern’lere sahip oldukları için filter bu servlete gelen requestleri dikkate almayacaktır. 

CustomFilter sınıfını incelersek chain.doFilter(req,resp) satırını görürüz. Burada server’a ‘Bu request ile ilgili işlemleri yaptım. Controller’a gitmeye hak kazandı.’ mesajı verilir. Eğer bir giriş doğrulama yapacaksak filter kullanabileceğimizi söylemiştik. Bunun için yapılacak işlemleri sıralamak gerekirse;

  • Url’i eşleşen controllara gelen requesti filtre yakalar.
  • Yakaladığı request teki kullanıcı adı ve şifre parametrelerini getParameter() methodu ile bulur.
  • Veri tabanından bu bilgilerle eşleşen bir kayıt olup olmadığına bakılır. 
  • Eğer böyle bir kayıt mevcutsa chain.doFilter(req,res) kod parçacığı ile request in geçişine izin verilir.
  • Girilen bilgiler hatalıysa yani herhangi bir kayıt bulunamadıysa kullanıcıya hata mesajı gösterilir.

FilterConfig(İnterfce)

FilterConfig nesnesi, web server tarafından oluşturulur. Bu nesne web.xml dosyasından yapılandırma bilgilerini almak için kullanılır. Yukarıdaki örneği baz alarak biz web.xml dosyasına bir şey yazmadık diyebilirsiniz fakat anotasyonlar içine girdiğimiz bilgilerin de web.xml dosyasında olduğu kabul edilir.

FilterConfig Methodları
  • public void init(FilterConfig filterConfig) : Bu method yalnızca servlet başlatıldığında bir kez çalışır.
  • public String getInitParameter(String paramName) : Adı verilen parametrenin değerini döndürür.
  • public Enumeration getInitParameterNames() : Tanımlanan tüm parametrelerin adlarını bir Enumeration nesnesi olarak döndürür.
  • public ServletContext getServletContext() : ServletContext nesnesini döndürür.

Bir sonraki dersimizde Servlet ile iligili çoğu özelliği barındıran bir örnek inceleyeceğiz. İyi çalışamalar dilerim.

Share this Post

Leave a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*
*