Skip to content

9. Örnek 07 – Form etiketleri

Aşağıdaki formu oluşturup kullanacağız:

Metin giriş alanı için gördüğümüz parametre enjeksiyon kavramını, bir formdaki diğer HTML öğelerine de genişleteceğiz.

9.1. NetBeans projesi

  • [1], proje görünümleri [Formx.JSP]
  • [2]'te, Struts yapılandırma dosyası ve uluslararasılaştırılmış mesajlar
  • [3]'e, eylemler [Formx.java]'e ve başka bir Struts yapılandırma dosyasına aktarılır.

9.2. Struts yapılandırması

[struts.xml] dosyası şu şekildedir:


<?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>
  <constant name="struts.custom.i18n.resources" value="messages" />
  
  <include file="example/example.xml"/>

  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Form</param>
        <param name="namespace">/example</param>
      </result>
    </action>
  </package>
</struts>
  • 9. satır: başka bir yapılandırma dosyası olan [example.xml]'i dahil eder. Eylemleri yapılandıracak olan bu dosyadır.
  • 11-19. satırlar: default paketi. URL / için bir yönlendirme adresi tanımlar. Bu adres, URL /example/Form.action adresine yönlendirilecektir.

Eylemleri yapılandıran [example.xml] dosyası şöyledir:


<?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 name="example" namespace="/example" extends="struts-default">
    <action name="Form" class="example.Form">
      <result name="success">/example/Form.JSP</result>
    </action>
    <action name="Form1" class="example.Form1">
      <result name="success">/example/Form1.JSP</result>
    </action>
    <action name="Form2" class="example.Form2">
      <result name="success">/example/Form2.JSP</result>
    </action>
  </package>
</struts>
  • 7-17. satırlar: /example/Form, /example/Form1 ve /example/Form2 eylemlerini tanımlar; burada /example ad alanı (7. satır), Formx ise eylemlerdir.
  • 8-10. satırlar: Form eyleminin yürütülmesi, /example/Form.JSP görünümünün görüntülenmesini sağlayacaktır.
  • 11-13. satırlar: Form1 eyleminin yürütülmesi, /example/Form1.JSP görünümünün görüntülenmesini sağlayacaktır.
  • satır 14-16: Form2 eyleminin yürütülmesi, /example/Form2.JSP görünümünün görüntülenmesini sağlayacaktır.

9.3. Mesaj dosyaları

Projenin uluslararasılaştırılması konusuna burada ayrıntılı olarak değinmeyeceğiz. Bu konuyu Örnek 01'de daha önce ele almıştık. Okuyucunun takip eden görünümleri anlayabilmesi için [messages.properties] dosyasının içeriğini veriyoruz.


Form.francais=Fran\u00E7ais
Form.anglais=Anglais
Form.titre=Struts 2 - les tags de formulaire
Form.message=Struts 2 - les tags de formulaire
Form.langues=langues
Form.textfield=1-textfield
Form.password=2-password
Form.textarea=3-textarea
Form.select1=4-select (multiple=false, size=1)
Form.select1.header=<-- select1 -->
Form.select2=5-select (multiple=false, size=3)
Form.select3=6-select (multiple=true, size=3)
Form.radio=7-radio
Form.checkbox=8-checkbox
Form.checkboxlist=9-checkboxlist
Form.hidden=10-hidden
Form.submitText=Valider
Form.buttonRazText=Raz
Confirmation.message=Confirmation des valeurs saisies
Confirmation.champ=champ
Confirmation.valeur=valeur
Confirmation.textfield=1-textfield
Confirmation.password=2-password
Confirmation.textarea=3-textarea
Confirmation.select1=4-select (multiple=false, size=1)
Confirmation.select2=5-select (multiple=false, size=3)
Confirmation.select3=6-select (multiple=true, size=3)
Confirmation.radio=7-radio
Confirmation.checkbox=8-checkbox
Confirmation.checkboxlist=9-checkboxlist
Confirmation.hidden=10-hidden

9.4. [Form.JSP] görünümü – giriş bölümü

Görsel görünümü şu şekildedir:

 

Şu şekildedir:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Form.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Form.message"/></h2>
    <h3><s:text name="Form.langues"/></h3>
    <ul>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">en</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.anglais"/></s:a>
      </li>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">fr</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.francais"/></s:a>
      </li>
    </ul>
    <s:form name="formulaire">
      <s:textfield name="textfield" key="Form.textfield" />
      <s:password name="password" key="Form.password"/>
      <s:textarea name="textarea" key="Form.textarea" cols="40" rows="5"/>
      <s:select name="select1" list="select1Values" size="1" key="Form.select1" headerValue="<-- select 1 -->" headerKey="-1" />
      <s:select name="select2" size="3" list="select2Values" key="Form.select2"/>
      <s:select name="select3" size="3" list="select3Values" key="Form.select3" multiple="true"/>
      <s:radio name="radio" list="radioValues" key="Form.radio"/>
      <s:checkbox name="checkbox" key="Form.checkbox"/>
      <s:checkboxlist name="checkboxlist" list="checkboxlistValues" key="Form.checkboxlist"/>
      <s:hidden name="hidden" key="Form.hidden"/>
      <s:submit key="Form.submitText" name="submitText"/>
    </s:form>
    <hr/>
 ...
  </body>
</html>
  • Form 26. satırda başlıyor ve 38. satırda bitiyor. 26. satırda, action özniteliği yok. Bu öznitelik, form verilerinin hangi eyleme gönderileceğini belirtir. action özniteliği bulunmadığında, veriler görünümün görüntülenmesine yol açan eyleme gönderilir; buradaki eylem [Form]'tir.
  • 27. satır: bir giriş alanı. key özniteliği, bu alanın etiketini belirtir. name özniteliği ise gönderilecek parametrenin adıdır. Bu alan için gönderilecek dize şu şekilde olacaktır:
textfield=texte_saisi

Parametre adı, [Form] eyleminin bir alanına karşılık gelir. texte_saisi giriş alanının değeri, burada [Form] eyleminin textfield alanına aktarılacaktır. Tersine, [Form] eyleminin ardından [Form.JSP] görünümü görüntülenirse, giriş alanının değeri [Form] eyleminin textfield alanındaki değer olacaktır. Dolayısıyla bu alan hem okuma hem de yazma amacıyla kullanılır. Bunun için [Form] sınıfında getTextField ve setTextField yöntemleri bulunmalıdır.

Bu mantık, bundan sonra gelecek tüm giriş etiketleri için geçerlidir. Bunu tekrar etmeyeceğiz.

  • 28. satır: şifre girişi. [Form] eylemine gönderilen dize şu biçimde olacaktır
password=mot_de_passe_saisi

[Form] eyleminde, get / set yöntemlerine sahip bir password alanı bulunmalıdır.

  • 29. satır: 5 satır ve 40 sütunluk bir alana çok satırlı metin girişi. [Form] eylemine gönderilen dize şu şekilde olacaktır
textarea=saisie

[Form] eyleminde, get / set yöntemlerine sahip bir textarea alanı bulunmalıdır.

  • 30. satır: Tek seçimli bir açılır liste (size=1). Listeden yalnızca bir değer seçilebilir. [Form] eylemine gönderilen dize şu şekilde olacaktır:
select1=valeur_sélectionnée

[Form] eyleminde, get / set yöntemlerine sahip bir select1 alanı bulunmalıdır.

key özniteliği, listenin etiketidir. list özniteliği, açılır menüye eklenecek değerlerin listesini tanımlar. Burada, açılır menüyü doldurmak için [Form] eyleminin getSelect1Values yöntemi çağrılacaktır. Bu yöntem bir koleksiyon, bir sözlük veya bir dizi döndürebilir. Burada, [chaine1, chaine2, ...] adlı bir karakter dizisi dizisi döndürecek ve bu da aşağıdaki HTML kodunu oluşturacaktır:


<option value="chaine1">chaine1</option>
<option value="chaine2">chaine2</option>
...

<option>...</option> etiketleri arasındaki metin, açılır menüde görüntülenecektir. value özniteliği, kullanıcı tarafından bu seçenek seçildiğinde gönderilecek değeri belirtir. Burada value özniteliği ile açılır menüde görüntülenen metin aynıdır. Çoğu zaman durum böyle değildir. İkinci seçenek seçilirse, aşağıdaki dize [Form] eylemine gönderilecektir:

select1=chaine2

[Form].select1 alanı bu durumda chaine2 değerini alacaktır. Tersine, form görüntülenirken bu alanın değeri chaine3 ise, görsel olarak 3. öğe


<option value="chaine3">chaine3</option>

seçili olarak görünecektir.

headerValue özniteliği, açılır menünün ilk seçeneği olarak görüntülenecek metni belirler; headerKey ise bu seçenek kullanıcı tarafından seçildiğinde gönderilecek değeri belirler.

  • 31. satır: Burada da 3 öğeli bir liste (size=3) bulunmaktadır: Tek bir öğenin görüldüğü önceki listenin aksine, burada listenin 3 öğesi görünecektir. Seçim yöntemi aynı kalır. Yalnızca bir öğe seçilebilir.
  • 32. satır: Yine bir liste, ancak bu sefer çoklu seçim yapılabilir (multiple=true). Bu durumda, [Form] eylemine gönderilen değer şu şekilde olacaktır:
select3=chaine2&select3=chaine5

eğer chaine2 ve chaine5 seçenekleri seçilmişse. Aynı parametre için (burada select3) birden fazla değer kaydedildiğinde, eylemin parametrenin adını taşıyan bir alana sahip olması ve tableau türünde olması gerekir. Dolayısıyla, örneğin burada [Form] eylemi şu tür bir alana sahip olabilir:

String[] select3 ;

ve buna ait get / set yöntemleri. select3 dizisi, [chaine2,chaine5] karakter dizisi dizisini alacaktır. Tersine, [Form.JSP] görünümünün görüntülenmesinde, [Form].select3 alanının değerleri, select3 listesinde hangi seçeneklerin seçili olarak görüneceğini belirler. Burada da okuma/yazma işlemi devam eder.

  • 33. satır: bir radyo düğmesi grubu. Grubun etiketi, key özniteliği ile sağlanır. Tek tek düğmelerin etiketleri ise list özniteliği ile sağlanır. Bu özniteliğin değeri, bir koleksiyon, sözlük veya dizi döndürmesi gereken [Form] eyleminin bir yönteminin adıdır. Burada, [Form].getRadioValues yöntemi, [chaine1,chaine2,...] karakter dizisi dizisini döndürecek ve bu da aşağıdaki HTML etiketlerini oluşturacaktır:

<input type="radio" name="radio" ... value="chaine1"/>chaine1
<input type="radio" name="radio" ... value="chaine2"/>chaine2
...

chaine2 radyo düğmesi işaretlenirse, gönderilen değer şöyledir:

radio=chaine2

olur ve bu değer [Form].radio alanına eklenir.

  • 34. satır: bir onay kutusu. İşaretlenirse, aşağıdaki parametre dizesi [Form] eylemine gönderilecektir
checkbox=true

İşaretlenmemişse, hiçbir parametre dizisi gönderilmez. Struts 2'nin dahili bir mekanizması vardır; bu mekanizma sayesinde her şey sanki

checkbox=false

dizesi gönderilmiş gibi davranır.

  • 35. satır: bir onay kutusu listesi. Birden fazla onay kutusu işaretlenebilir. Grubun etiketi, key özniteliği tarafından sağlanır. Tek tek onay kutularının etiketleri, list özniteliği tarafından sağlanır. Bu özniteliğin değeri, bir koleksiyon, sözlük veya dizi döndürmesi gereken [Form] eyleminin bir yönteminin adıdır. Burada, [Form].getCheckboxlistValues yöntemi, [chaine1,chaine2,...] adlı bir dize dizisi döndürür ve bu da aşağıdaki HTML etiketlerini oluşturur:

<input type="checkbox" name="checkboxlist" ... value="chaine1"/>chaine1
<input type="checkbox" name="checkboxlist" ... value="chaine2"/>chaine2
...

Kullanıcı, chaine2 ve chaine5 etiketli kutuları seçerse, aşağıdaki karakter dizisi [Form] eylemine gönderilecektir:

checkboxlist=chaine2&checkboxlist=chaine5

[chaine2, chaine5] tablosu, [Form].checkboxlist alanına atanacaktır; bu nedenle bu alan, çoklu seçim listelerinde olduğu gibi karakter dizisi tablosu türünde olmalıdır. Tersine, [Form.JSP] görünümünün görüntülenmesinde, [Form].checkboxlist alanının değerleri, hangi onay kutularının işaretleneceğini belirler.

  • 36. satır: gizli bir alan. Gizli alan, kullanıcı tarafından girilmeden gönderilen bir alandır. Değeri programcı tarafından belirlenir. Burada gizli alan, değerini [Form].hidden alanından alacaktır. Bu değer şu biçimde gönderilecektir:
hidden=qqchose

şeklinde gönderilecek ve [Form].hidden alanına yeniden atanacaktır.

  • 37. satır: submit türünde bir düğme. Bu düğmeye tıklandığında, formdaki tüm değerler [Form] eylemine gönderilecektir. Gönderilen parametre dizisi şu şekilde olacaktır:
textfield=texte&password=&textarea=ligne1%0D%0Aligne2%0D%0A&select1=z%C3%A9ro&select2=trois&select3=z%C3%A9ro&select3=deux&__multiselect_select3=&radio=bleu&checkbox=true&__checkbox_checkbox=true&checkboxlist=v%C3%A9lo&checkboxlist=bus&__multiselect_checkboxlist=&hidden=initial&submitText=Valider 

9.5. [Form] eylemi – giriş bölümü

Kodu şu şekildedir:


package example;

import com.opensymphony.xwork2.ActionSupport;

public class Form extends ActionSupport {

  // parametresiz oluşturucu
  public Form() {
  }
  // form alanları
  private String textfield = "texte";
  private String password = "secret";
  private String textarea = "ligne1\nligne2\n";
  private String select1 = "zéro";
  private String[] select1Values = new String[]{"zéro", "un", "deux"};
  private String select2 = "trois";
  private String[] select2Values = new String[]{"zéro", "un", "deux", "trois", "quatre"};
  private String[] select3 = new String[]{"zéro", "deux"};
  private String[] select3Values = new String[]{"zéro", "un", "deux", "trois", "quatre"};
  private String radio = "bleu";
  private String[] radioValues = new String[]{"bleu", "blanc", "rouge"};
  private Boolean checkbox = false;
  private String[] checkboxlist = new String[]{"vélo", "bus"};
  private String[] checkboxlistValues = new String[]{"voiture", "tram", "vélo", "bus", "métro"};
  private String hidden = "initial";
  private String submitText;

  // select3 alanında seçilen değerler
  public String getSelect3SelectedValues() {
    return getValue(select3);
  }

  // checkboxlist alanında seçilen değerler
  public String getCheckboxlistSelectedValues() {
    return getValue(checkboxlist);
  }

  // yardımcı yöntem
  public String getValue(String[] values) {
    String result = "";
    for (String value : values) {
      result += " " + value;
    }
    return result;
  }

// alanların getter ve setter'ları
  ....
}
  • 1. satır: Formdaki textfield etiketiyle ilişkili alan. Bu giriş alanını başlatmak ve değerini almak için kullanılır. POST eylemi sırasında, bu alana girilen değeri alır.
  • 2. satır: Formdaki password etiketiyle ilişkili alan. POST çağrıldığında, bu alana girilen değeri alır.
  • 13. satır: Formdaki textarea etiketiyle ilişkilidir. POST etiketine gönderildiğinde, bu alana girilen metni alır.
  • 14. satır: Formdaki select1 etiketiyle ilişkilidir; tek seçimli bir liste içerir. Başlangıç değeri, açılır menüden bir öğeyi seçer. value özniteliği bu değere eşit olan öğe seçilecektir. POST işlevi çalıştırıldığında, açılır menüden seçilen seçeneğin value özniteliği bu alana aktarılır.
  • 15. satır: select1 açılır menüsüne eklenecek karakter dizileri.
  • 16. ve 17. satırlar: select1 ile aynı
  • 18. satır: Formdaki select1 etiketiyle ilişkili, çoklu seçim listesi. Tablodaki başlangıç değerleri, listenin karşılık gelen öğelerini seçer. value özniteliği bu öğelerden birine eşit olan öğeler seçilecektir. POST işlendiğinde, açılır menüden seçilen farklı seçeneklerin value öznitelikleri alınır.
  • 19. satır: select3 listesine eklenecek karakter dizileri
  • 20. satır: Formdaki radio etiketiyle ilişkilidir. Bu değer, value özniteliği bu değere eşit olan radyo düğmelerinden birini işaretlemek için kullanılır. POST çağrıldığında, işaretli radyo düğmesinin değerini alır.
  • 21. satır: Radyo düğmelerinin çeşitli etiketleri ve değerleri.
  • 22. satır: Formdaki checkbox etiketiyle ilişkilidir. Başlangıç değeri, kutucuğu işaretlemek veya işaretini kaldırmak için kullanılır. POST çağrıldığında, kutucuk işaretlenmişse true değerini, aksi takdirde false değerini alır.
  • 23. satır: Formdaki checkboxlist etiketiyle ilişkilidir. Tablodaki başlangıç değerleri, karşılık gelen onay kutularını seçer. value özniteliği bu başlangıç değerlerinden birine eşit olan onay kutuları işaretlenecektir. POST işleme alındığında, işaretli farklı kutuların value özniteliklerini alır.
  • 24. satır: checkboxlist'teki kutuların etiketlerini dolduracak karakter dizileri.
  • 25. satır: Gizli alan hidden ile ilişkilidir. Başlangıç değeri, gizli alanın değerini belirleyecektir. POST anında, kullanıcı bu değeri değiştiremeyeceği için aynı değeri alacaktır.
  • 26. satır: submit etiketiyle ilişkilidir. POST çalıştırıldığında, düğmenin etiketini alır. Bu alan kullanılmasa da olur.
  • 29., 34. ve 39. satırlardaki yöntemler biraz ileride açıklanacaktır.

9.6. [Form.JSP] görünümü – Onay bölümü

[Form.JSP] görünümünde, henüz incelenmemiş bir "Girişlerin Onaylanması" bölümü bulunmaktadır:

 

Kodu şu şekildedir:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
...
    <hr/>
    <h2><s:text name="Confirmation.message"/></h2>
    <table border="1">
      <tr>
        <th><s:text name="Confirmation.champ"/></th>
        <th><s:text name="Confirmation.valeur"/></th>
      </tr>
      <tr>
        <td><s:text name="Form.textfield"/></td>
        <td><s:property value="textfield"/>
      </tr>
      <tr>
        <td><s:text name="Form.password"/></td>
        <td><s:property value="password"/>
      </tr>
      <tr>
        <td><s:text name="Form.textarea"/></td>
        <td><s:property value="textarea"/>
      </tr>
      <tr>
        <td><s:text name="Form.select1"/></td>
        <td><s:property value="select1"/>
      </tr>
      <tr>
        <td><s:text name="Form.select2"/></td>
        <td><s:property value="select2"/>
      </tr>
      <tr>
        <td><s:text name="Form.select3"/></td>
        <td><s:property value="select3SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio"/></td>
        <td><s:property value="radio"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkbox"/></td>
        <td><s:property value="checkbox"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist"/></td>
        <td><s:property value="checkboxlistSelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.hidden"/></td>
        <td><s:property value="hidden"/>
      </tr>
    </table>
  </body>
</html>
  • 13. satır: [Form].textfield alanının değerini gösterir
  • 17. satır: [Form].password alanının değerini gösterir
  • 21. satır: [Form].textarea alanının değerini görüntüler
  • 25. satır: [Form].select1 alanının değerini görüntüler
  • 29. satır: [Form].select2 alanının değerini görüntüler
  • 33. satır: [Form].select3 tablosundaki değerleri görüntüler. Bunun için [Form].getSelect3SelectedValues yöntemini kullanır.
  • 37. satır: [Form].radio alanının değerini görüntüler
  • 41. satır: [Form].checkbox alanının değerini görüntüler
  • 45. satır: [Form].checkboxlist tablosundaki değerleri görüntüler. Bunun için [Form].getCheckboxlistSelectedValues yöntemini kullanın.
  • 49. satır: [Form].hidden alanının değerini görüntüler

9.7. [Form] eylemi – onay bölümü

Yukarıda bahsedilen getSelect3SelectedValues ve getCheckboxlistSelectedValues yöntemleri, [Form] sınıfında tanımlanmıştır:


  // select3 alanında seçilen değerler
  public String getSelect3SelectedValues() {
    return getValue(select3);
  }

  // checkboxlist alanında seçilen değerler
  public String getCheckboxlistSelectedValues() {
    return getValue(checkboxlist);
  }

  // yardımcı yöntem
  public String getValue(String[] values) {
    String result = "";
    for (String value : values) {
      result += " " + value;
    }
    return result;
}

Sadece görüntülemeleri gereken tabloların öğelerini birleştiriyorlar.

9.8. Testler

NetBeans projesini çalıştırdığımızda, aşağıdaki başlangıç sayfası karşımıza çıkar:

[1] ve [2]'te görüntülenen değerler, [Form] eyleminin alanlarındaki başlangıç değerlerinden alınmaktadır. Birkaç örnek verelim:


private String textarea = "ligne1\nligne2\n";

textarea alanının değeri, [1A] ve [2A]'te görüntülenen değerleri açıklar.


private String[] select3 = new String[]{"zéro", "deux"};
private String[] select3Values = new String[]{"zéro", "un", "deux", "trois", "quatre"};

select3Values alanının değeri, [1B]'teki listenin içeriğini açıklar. select3 alanının değeri, [1B]'te seçilen ve [2B]'te görüntülenen öğeleri açıklar.

Formda başka değerler girip formu onaylarsak, girilen değerler [Form] eyleminin ilgili alanlarına gönderilir. Ardından, [Form.JSP] görünümü yeniden görüntülenir. Dolayısıyla, başlangıçtaki değerlerin gönderilen değerlerle değiştirilmiş olması dışında, önceki durumla aynı durumdayız. İşte bir örnek:

9.9. [Form1] eylemi ve [Form1.JSP] görünümü

[example.xml] yapılandırma dosyası, aşağıdaki [Form1] eylemini yapılandırır:


<?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 name="example" namespace="/example" extends="struts-default">
    <action name="Form" class="example.Form">
      <result name="success">/example/Form.JSP</result>
    </action>
    <action name="Form1" class="example.Form1">
      <result name="success">/example/Form1.JSP</result>
    </action>
    <action name="Form2" class="example.Form2">
      <result name="success">/example/Form2.JSP</result>
    </action>
  </package>
</struts>

11-13. satırlarda, [Form1] eyleminin çağrılması, [Form1.JSP] görünümünü oluşturur.

[Form1] eylemi şöyledir:


package example;

import com.opensymphony.xwork2.ActionSupport;

public class Form1 extends ActionSupport{

  // parametresiz oluşturucu
  public Form1() {
  }
  // form alanları
  private Data data=new Data();

  /**
   * @return the data
   */
  public Data getData() {
    return data;
  }

  /**
   * @param data the data to set
   */
  public void setData(Data data) {
    this.data = data;
  }
}

[Form1] eylemi, [Form] eylemiyle aynıdır; tek farkı, şablon kısmının 11. satırdaki [Data] adlı bir alt sınıfa taşınmış olmasıdır. [Data] sınıfı şu şekildedir:


package example;

public class Data {

  // parametresiz oluşturucu
  public Data() {
  }
  
// form alanları
  private String textfield = "texte";
  private String password = "secret";
  private String textarea = "ligne1\nligne2\n";
  private String select1 = "zéro";
  private String[] select1Values = new String[]{"zéro", "un", "deux"};
  private String select2 = "trois";
  private String[] select2Values = new String[]{"zéro", "un", "deux", "trois", "quatre"};
  private String[] select3 = new String[]{"zéro", "deux"};
  private String[] select3Values = new String[]{"zéro", "un", "deux", "trois", "quatre"};
  private String radio="bleu";
  private String[] radioValues = new String[]{"bleu", "blanc", "rouge"};
  private Boolean checkbox = false;
  private String[] checkboxlist = new String[]{"vélo", "bus"};
  private String[] checkboxlistValues = new String[]{"voiture", "tram", "vélo", "bus", "métro"};
  private String hidden = "initial";
  private String submitText;

  // select3 alanında seçilen değerler
  public String getSelect3SelectedValues() {
    return getValue(select3);
  }

  // checkboxlist alanında seçilen değerler
  public String getCheckboxlistSelectedValues() {
    return getValue(checkboxlist);
  }

  // yardımcı yöntem
  public String getValue(String[] values) {
    String result = "";
    for (String value : values) {
      result += " " + value;
    }
    return result;
  }

  // alıcı ve ayarlayıcılar
....

}

Daha önce [Form] eyleminde bildirilen alanları burada da görüyoruz.

Mantıken, [Form1.JSP] görünümü, [Form.JSP] görünümüne benzerdir:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Form.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Form.message"/></h2>
    <h3><s:text name="Form.langues"/></h3>
    <ul>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">en</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.anglais"/></s:a>
      </li>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">fr</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.francais"/></s:a>
      </li>
    </ul>
    <s:form name="formulaire">
      <s:textfield name="data.textfield" key="Form.textfield" />
      <s:password name="data.password" key="Form.password"/>
      <s:textarea name="data.textarea" key="Form.textarea" cols="40" rows="5"/>
      <s:select name="data.select1" list="data.select1Values" size="1" key="Form.select1" headerValue="<-- select 1 -->" headerKey="-1" />
      <s:select name="data.select2" size="3" list="data.select2Values" key="Form.select2"/>
      <s:select name="data.select3" size="3" list="data.select3Values" key="Form.select3" multiple="true"/>
      <s:radio name="data.radio" list="data.radioValues" key="Form.radio"/>
      <s:checkbox name="data.checkbox" key="Form.checkbox"/>
      <s:checkboxlist name="data.checkboxlist" list="data.checkboxlistValues" key="Form.checkboxlist"/>
      <s:hidden name="data.hidden" key="Form.hidden"/>
      <s:submit key="Form.submitText" name="data.submitText"/>
    </s:form>
    <hr/>
    <h2><s:text name="Confirmation.message"/></h2>
    <table border="1">
      <tr>
        <th><s:text name="Confirmation.champ"/></th>
        <th><s:text name="Confirmation.valeur"/></th>
      </tr>
      <tr>
        <td><s:text name="Form.textfield"/></td>
        <td><s:property value="data.textfield"/>
      </tr>
      <tr>
        <td><s:text name="Form.password"/></td>
        <td><s:property value="data.password"/>
      </tr>
      <tr>
        <td><s:text name="Form.textarea"/></td>
        <td><s:property value="data.textarea"/>
      </tr>
      <tr>
        <td><s:text name="Form.select1"/></td>
        <td><s:property value="data.select1"/>
      </tr>
      <tr>
        <td><s:text name="Form.select2"/></td>
        <td><s:property value="data.select2"/>
      </tr>
      <tr>
        <td><s:text name="Form.select3"/></td>
        <td><s:property value="data.select3SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio"/></td>
        <td><s:property value="data.radio"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkbox"/></td>
        <td><s:property value="data.checkbox"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist"/></td>
        <td><s:property value="data.checkboxlistSelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.hidden"/></td>
        <td><s:property value="data.hidden"/>
      </tr>
    </table>
  </body>
</html>

[Form] ve [Form1] görünümleri arasındaki fark, aşağıda gösterilen 27. satırla açıklanabilir:


<s:textfield name="data.textfield" key="Form.textfield" />

Giriş alanı, [Form1] eyleminin data.textfield alanına okuma ve yazma açısından bağlıdır. Hatırlatmak gerekirse, yürütme sonrasında [Form1] eyleminin özelliklerine görünümden erişilebilir. Böylece, yukarıdaki name özniteliği, [Form1].getData().getTextField() şeklinde değerlendirilecektir. Bu nedenle, önceki iki get yönteminin mevcut olması gerekir.

9.10. [Form2] eylemi ve [Form2.JSP] görünümü

[example.xml] yapılandırma dosyası, aşağıdaki [Form2] eylemini yapılandırır:


<?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 name="example" namespace="/example" extends="struts-default">
    <action name="Form" class="example.Form">
      <result name="success">/example/Form.JSP</result>
    </action>
    <action name="Form1" class="example.Form1">
      <result name="success">/example/Form1.JSP</result>
    </action>
    <action name="Form2" class="example.Form2">
      <result name="success">/example/Form2.JSP</result>
    </action>
  </package>
</struts>

14-16. satırlarda, [Form2] eyleminin çağrılması, [Form2.JSP] görünümünü oluşturur.

[Form2] eylemi şöyledir:


package example;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class Form2 extends ActionSupport implements ModelDriven {

  // parametresiz oluşturucu
  public Form2() {
  }
  // eylem modeli
  public Object getModel() {
    return new Data();
  }
}
  • 6. satır: [Form2] eylemi, [ModelDriven] arayüzünü uygular. Uygulanacak tek bir yöntem vardır: 12. satırdaki getModel yöntemi. Bu yöntem, daha önce incelenen [Data] sınıfının bir örneğini döndürür.

[Form2] eyleminin [ModelDriven] arayüzünü uygulamasının sonucu şudur: [Form2] eyleminin ardından görüntülenen görünüm, [Form2] eyleminin model özelliklerine doğrudan erişebilir; bu model, getModel() yöntemi tarafından oluşturulur. Ayrıca, [Form2.JSP] görünümü, başlangıçtaki [Form] eylemi ile olduğu haline geri döner:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Form.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Form.message"/></h2>
    <h3><s:text name="Form.langues"/></h3>
    <ul>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">en</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.anglais"/></s:a>
      </li>
      <li>
        <s:url id="URL" action="Form">
          <s:param name="request_locale">fr</s:param>
        </s:url>
        <s:a href="%{URL}"><s:text name="Form.francais"/></s:a>
      </li>
    </ul>
    <s:form name="formulaire">
      <s:textfield name="textfield" key="Form.textfield" />
      <s:password name="password" key="Form.password"/>
      <s:textarea name="textarea" key="Form.textarea" cols="40" rows="5"/>
      <s:select name="select1" list="select1Values" size="1" key="Form.select1" headerValue="<-- select 1 -->" headerKey="-1" />
      <s:select name="select2" size="3" list="select2Values" key="Form.select2"/>
      <s:select name="select3" size="3" list="select3Values" key="Form.select3" multiple="true"/>
      <s:radio name="radio" list="radioValues" key="Form.radio"/>
      <s:checkbox name="checkbox" key="Form.checkbox"/>
      <s:checkboxlist name="checkboxlist" list="checkboxlistValues" key="Form.checkboxlist"/>
      <s:hidden name="hidden" key="Form.hidden"/>
      <s:submit key="Form.submitText" name="submitText"/>
    </s:form>
    <hr/>
    <h2><s:text name="Confirmation.message"/></h2>
    <table border="1">
      <tr>
        <th><s:text name="Confirmation.champ"/></th>
        <th><s:text name="Confirmation.valeur"/></th>
      </tr>
      <tr>
        <td><s:text name="Form.textfield"/></td>
        <td><s:property value="textfield"/>
      </tr>
      <tr>
        <td><s:text name="Form.password"/></td>
        <td><s:property value="password"/>
      </tr>
      <tr>
        <td><s:text name="Form.textarea"/></td>
        <td><s:property value="textarea"/>
      </tr>
      <tr>
        <td><s:text name="Form.select1"/></td>
        <td><s:property value="select1"/>
      </tr>
      <tr>
        <td><s:text name="Form.select2"/></td>
        <td><s:property value="select2"/>
      </tr>
      <tr>
        <td><s:text name="Form.select3"/></td>
        <td><s:property value="select3SelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.radio"/></td>
        <td><s:property value="radio"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkbox"/></td>
        <td><s:property value="checkbox"/>
      </tr>
      <tr>
        <td><s:text name="Form.checkboxlist"/></td>
        <td><s:property value="checkboxlistSelectedValues"/>
      </tr>
      <tr>
        <td><s:text name="Form.hidden"/></td>
        <td><s:property value="hidden"/>
      </tr>
    </table>
  </body>
</html>

Böylece, daha önce şu şekilde olan 27. satır:


<s:textfield name="data.textfield" key="Form.textfield" />

şu hale gelir:


<s:textfield name="textfield" key="Form.textfield" />

Modeli görünümün dışına yerleştirmenin avantajı, bu mimarinin MVC mimarisinin her bir öğesinin işlevlerini daha net bir şekilde sınırlandırmasıdır. M modeli, bir sınıfla açıkça tanımlanmıştır. Ayrıca, model eylemlerden önce mevcut olabilir. Dolayısıyla, bir web uygulaması bir kişi veritabanını yönetiyorsa, Personne sınıfının var olması muhtemeldir. Bir eylem, yeni bir kişi oluşturmak için bir giriş formu sunuyorsa, bu eylemin modeli bellidir: Personne sınıfıdır.

[Form] eylemindan [Form2] eylemine geçişin ne kadar basit olduğunu gördük:

  • V görünümünün M şablonu ayrı bir sınıfa kapsüllenmiştir
  • bu modeli kullanan görünümü oluşturan eylem, ModelDriven arayüzünü, model M'nin bir örneğini döndüren getModel yöntemiyle birlikte uygular. Eylem, bu şekilde Struts 2'nin C denetleyicisinin bir uzantısı, yani FilterDispatcher sınıfı olarak görülebilir.

Okuyucu, bu yaklaşımı bundan sonra açıklanacak tüm eylemlere uygulayabilir.