Struts 2’de Kendi Interceptor Sınıfımızı Yaratmak

Struts 2’de Interceptors sayesinde tüm istekler ve yönlendirmeler üzerinde işlemler gerçekleştirebiliriz. Bir web sayfasından gönderilen parametre Interceptors sayesinde Action sınıfı içerisindeki bir değişkenin değerine set edilir.  Ayrıca action metodumuz (Action sınıfındaki execute() metodu) çalışmadan önce ve sonra yapılacak işler varsa, Interceptors bize bu işleri gerçekleştirme imkanını sağlar.

Interceptors konfigurasyon dosyasında (struts.xml) belirli bir paket tanımı içerisinde tanımlanır. Konfigurasyon dosyalarında tanımladığımız paketleri genellikle struts-default.xml dosyasından extend ederiz. Bu sayede bu dosya içerisinde tanımlanmış tüm özellikleri kullanabiliriz.

[box type=”info”] struts-default.xml dosyası struts2-core-xxx.jar dosyası içerisindedir.[/box]

struts-default.xml dosyası içerisinde de halihazırda tanımlanmış birçok Interceptor vardır. Çoğu uygulama için bu tanımlar yeterli olacaktır.

Interceptor tanımları struts.xml dosyasında basit anlamda aşağıdaki gibi yapılır.

[box type=”warning”] Aşağıdaki tanım struts-default.xml dosyasından örnek olması amacıyla alınmıştır.[/box]

[codesyntax lang=”xml” lines=”no”]

<struts>
   ...
   <package name="struts-default">
      <interceptors>
         <interceptor name="alias"/>
         <interceptor name="autowiring"/>
         ...
      </interceptors>
   </package>
   ...
</struts>

[/codesyntax]

Konfigurasyon dosyasında birden fazla action tanımlanmışsa ve her bir action aynı Interceptor’ları kullanıyorsa, kullanılan Interceptor’lar bir stack tanımı yapılarak referans gösterilir.

[codesyntax lang="xml" lines="no"]
<package name="default" namespace="/" extends="struts-default">
     <interceptors>
        <interceptor-stack name="stack1">
             <interceptor-ref name="timer"/>
             <interceptor-ref name="logger"/>
             <interceptor-ref name="defaultStack" />
        </interceptor-stack>
    </interceptors>

    <action name="login">
        <interceptor-ref name="stack1"/>
        <result name="success">/menu.jsp</result>
    </action>

    <action name="logout">
        <interceptor-ref name="stack1"/>
        <result name="success">/logout.jsp</result>
    </action>
</package>
[/codesyntax]

[box type=”info”] Yukarıdaki örnekte timer, logger ve defaultstack isimli Interceptor’lar struts-default.xml dosyasında tanımlanmışlardır. İsterseniz kendi tanımladığınız Interceptor’ları da bir stack tanımı yaparak action içerisinde referans olarak verebilirsiniz.[/box]

Çok özel uygulamalar için kendi Interceptor sınıflarımızı yazma ihtiyacı duyabiliriz. Bu gibi durumlarda Interceptor sınıflarının nasıl tanımlandığını basit bir örnekle anlatmaya çalışayım.

Projemde kullandığım teknolojiler :

–          JDK 1.7

–          Eclipse Juno 4.2

–          Struts 2.3.8

–          Apache Tomcat 7

CustomInterceptor isminde yeni bir web projesi yaratıyorum.

İlk olarak JSP sayfamı tasarlıyorum.

index.jsp

[codesyntax lang=”html4strict” lines=”no”]

<%@ page language="java" contentType="text/html; charset=ISO-8859-9" pageEncoding="ISO-8859-9"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
	<body>
       		<s:a href="tikla">Interceptor Test</s:a>
	</body>
</html>

[/codesyntax]

Basit bir sayfa ve sadece tek bir link var. Şimdi linke tıkladığımızda çalışacak Action sınıfını tasarlıyorum.

TiklaAction.java

[codesyntax lang=”java” lines=”no”]

package sample;

public class TiklaAction {

       public String execute() {
             System.out.println("Action calisti");
             return "success";
       }
}

[/codesyntax]

Bu sınıf da basit bir POJO ve sadece konsola “Action calisti” yazarak sayfayı yönlendiriyor. Yönlendirilecek sayfayı tasarlayalım.

success.jsp

[codesyntax lang=”html4strict” lines=”no”]

<%@ page language="java" contentType="text/html; charset=ISO-8859-9" pageEncoding="ISO-8859-9"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
	<body>
       		<h1>Yönlendirilen Sayfa</h1>
	</body>
</html>

[/codesyntax]

Şimdi de Interceptor sınıflarımızı tasarlayalım. Bir sınıfın Interceptor olabilmesi için;

1-      Interceptor arayüzünü gerçekleştirmesi gerekir ya da

2-      Interceptor arayüzünü gerçekleştirmiş olan AbstractInterceptor sınıfından türemesi gerekir.

AbstractInterceptor sınıfını kullanıyorsak init() ve destroy() metotlarını ezme zorunluluğumuz kalmaz. Ben iki tane Interceptor sınıfı tanımlayacağım.

MyInterceptor1.java

[codesyntax lang=”java” lines=”no”]

package com.javauzmani.interceptors;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor1 extends AbstractInterceptor {
       private static final long serialVersionUID = -299349963368714122L;

       @Override
       public String intercept(ActionInvocation inv) throws Exception {
             System.out.println("MyInterceptor1 sinifinda action sinifindaki execute metodu calismadan once yapilacak isler");
             String invocationResult = inv.invoke()
             System.out.println("MyInterceptor1 sinifinda action sinifindaki execute metodu calistiktan sonra yapilacak isler");
             return invocationResult;
       }
}

[/codesyntax]

MyInterceptor2.java

[codesyntax lang=”java” lines=”no”]

package com.javauzmani.interceptors;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor2 extends AbstractInterceptor {
                private static final long serialVersionUID = -7461817391953291560L;

                @Override
                public String intercept(ActionInvocation inv) throws Exception {

                               System.out.println("MyInterceptor2 sinifinda action sinifindaki execute metodu calismadan once yapilacak isler");
                               String invocationResult = inv.invoke();
                               System.out.println("MyInterceptor2 sinifinda action sinifindaki execute metodu calistiktan sonra yapilacak isler");
                               return invocationResult;
                }
}

[/codesyntax]

Şimdi de konfigurasyon dosyasını tanımlayalım.

struts.xml

[codesyntax lang=”xml” lines=”no”]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC

       "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
       "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
             <package extends="struts-default" name="myPackage">
                    <interceptors>
                           <interceptor class="com.javauzmani.interceptors.MyInterceptor1" name="myInterceptor1"></interceptor>
                           <interceptor class="com.javauzmani.interceptors.MyInterceptor2" name="myInterceptor2"></interceptor>
                    </interceptors>

                    <action class="com.javauzmani.action.TiklaAction" name="tikla">
                           <interceptor-ref name="myInterceptor1"></interceptor-ref>
                           <interceptor-ref name="myInterceptor2"></interceptor-ref>
                           <result name="success">/success.jsp</result>
                    </action>
             </package>
</struts>

[/codesyntax]

Interceptor’lar konfigurasyon dosyasında tanımlandıkları sırada çalışırlar.

web.xml dosyası aşağıdaki gibidir.

[codesyntax lang=”xml” lines=”no”]

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

  <display-name>CustomInterceptor</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

[/codesyntax]

Projemizi çalıştırdığımızda index.jsp sayfası gelecektir.

1

Linke tıkladığımızda sayfa success.jsp’ye yönlendirilir.

2

Konsol çıktısı da aşağıdaki gibi olur.

3

Action sınıfları Servlet sınıflarından farklı olarak thread-safe çalışırlar. Gelen her istek için Action sınıfının bir instance’ı yaratılır. Servlet’lerde ise aynı instance gelen her istek için kullanılır.

Fakat Interceptor’lardaki durum farklıdır. Action sınıfları thread-safe olsa da Interceptor’ların instance’ları bir defa yaratılır ve aynı Servlet’ler gibi her istek için kullanılırlar. Bu yüzden Interceptor sınıfları içerisindeki kodların thread-safe yazılması gerekir.

Yorum bırakın