Vážení čtenáři, blahopřeji! Právě se vám dostává do rukou první ze série článků, který učiní všechny předchozí i budoucí díly seriálu o Jakarta Struts zcela zbytečnými. Záměrem bylo sice pouze popsat jedno obyčejné DTDčko, leč chceme-li jeho komentář učinit srozumitelným, nevyhneme se tu více tu méně detailním exkursům do všech podstatných zákoutí problematiky tvorby aplikací pomocí Struts. Takže, chci-li vás prostřednictvím Intervalu oblažit dalšími články o tomto rámcovém systému, nezbývá, než pevně doufat ve vaši laskavou nepozornost.

V následujícím textu si podrobně popíšeme možnosti konfigurace aplikace třídy ActionServlet, která je jádrem aplikačního frameworku struts. Jak bylo zmíněno v předchozím článku, aplikaci konfigurujeme jednak standartním souborem WEB-INF/web.xml (tzv. deployment descriptor), kde na scénu uvádíme vlastní ActionServlet, a dále pak konfiguračním souborem samotných Struts, který se obvykle vyskytuje pod jménem WEB-INF/struts-config.xml. Pro nedostatek místa se v tomto díle detailněji zaměříme pouze na konfiguraci formulářů.

Vlastní DTD tohoto XML dokumentu si můžete stáhnout na adrese http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd. Nejedná se jen o suchý popis plný nesrozumitelných značek, ale obsahuje i místy docela podrobné komentáře.

Konfigurační soubor struts-config.xml musí být ohraničen kořenovou značkou struts-config. Uvnitř této značky se postupně nachází další elementy definující jednotlivé kousky strutsí aplikace:

  • data-sources – uvnitř tohoto elementu je možné definovat databázová spojení používané naší aplikací;
  • form-beans – formulářové třídy;
  • global-exceptions – výjimky, které se mají zpracovávat jednotným způsobem v celé aplikaci;
  • global-forwards – de facto aliasy pro jednotlivé zdroje. Díky těmto „forwards“ se můžeme v aplikaci odkazovat na symbolické názvy a ne přímo na konkrétní jména např. JSP stránek;
  • action-mappings – to nejdůležitější – přehled akcí (tedy námi vytvořených potomků třídy org.apache.struts.action.Action, které zapouzdřují velkou část aplikační logiky) a popisů jejich chování;
  • controller – konfigurace vlastního controlleru.

Žádný z výše zmíněných elementů se v konfiguračním souboru nesmí vyskytovat více než jednou. Všechny až na poslední controller definují chování určité skupiny prvků aplikace, které jsou uvnitř těchto „skupinových elementů“ popsány dalšími značkami (například data-sources může obsahovat několik tagů data-source, které definují jednotlivá databázová spojení).

Následující podelementy kořenové značky struts-config se mohou vyskytovat vícekrát a definují konkrétní samostatné komponenty:

  • message-resources – plné jméno properties souborů obsahující definici lokalizovaných textíků pro naši aplikaci;
  • plug-in – v podstatě jakákoli potvora, kterou potřebujeme inicializovat při startu naší aplikace (respektive jí odpovídající instance třídy ActionServlet).

Mimochodem, předchozí cca jednostránkové povídání v zjednodušené podobě zachycuje následující řádek DTD deklarace:

<!ELEMENT struts-config (data-sources?, form-beans?, global-exceptions?, global-forwards?, action-mappings?, controller?, message-resources*, plug-in*)
>

Otazník jako nejvýše jednou, hvězdička jako libovolně mnohokrát. Že to slavné DTD není až taková věda?

Nyní nám nezbývá, než se detailněji probrat všemi možnými konfiguračními elementy. Abychom neztratili nit s realitou, budeme vycházet z příkladu z minulého článku, jen ho tu a tam trochu rozšíříme. A protože článek je už teď dlouhý až až, začneme s tím nejdůležitějším a z minulého článku nejdůvěrněji známým – s formuláři a akcemi (dobře, akce už se nám sem nevejdou, tak ty přijdou na řadu hned příště).

form-beans

V příkladě z minulého článku jsme vytvářeli formulář pro registraci uživatele. Položkám HTML formuláře odpovídaly jednotlivé properties formulářové třídy RegistrationForm. A do struts-config.xml jsme uvedli následující:

<form-beans>   <form-bean name=“registrationForm“     type=“cz.templation.struts.sample1.RegistrationForm“ /> </form-beans>

Uvnitř elementu form-beans tedy definujeme jednotlivé formuláře pomocí podelementů form-bean. Tento podelement můžeme opatřit následujícími atributy:

  • className – chceme-li přetížit defaultní konfigurační třídu. Využití tohoto parametru názorně ukážeme později při definování akcí.
  • name – jednoznačný identifikátor formuláře. Bude použit později u definic akcí – bude nutné Controlleru sdělovat, v podobě které formulářové třídy očekává která akce uživatelem zaslaná data. Tento atribut je logicky povinný, bez něj bychom se na definici třídy nemohli odkázat a byla by nám tudíž k ničemu.
  • type – plné jméno třídy implemementující příslušný formulář. Vždy se musí jednat o potomka org.apache.struts.action.ActionForm (jako například výše zmíněná RegistrationForm z našeho příkladu). Tento atribut je rovněž povinný.

Z minulého dílu víme, jak takový jednoduchý formulář může vypadat a jak jej používat. Teď je vhodná chvíle doplnit si vědomosti o několika alternativách.

Dynamické formuláře

Struts nabízí od (zatím ne oficiálně stabilní) verze 1.1 navíc takzvané dynamické formuláře, pro které nemusíme vytvářet vlastní třídy. Dynamický formulář nám implementuje třída org.apache.struts.action.DynaActionForm, chceme-li tedy dynamických formulářů využít, uvedeme do atributu type název této třídy. Přirozenou otázkou je, jak definovat jednotlivé položky formuláře, pokud si nemůžeme definovat vlastní JavaBean třídu. A neméně přirozenou odpovědí je, že pro práci s formuláři postavenými na DynaActionForm slouží podelement form-property, kterými snadno a rychle docílíme obdobného efektu:

<form-beans>
  <form-bean name=“registrationForm“
    type=“org.apache.struts.action.DynaActionForm“>
    <form-property name=“login“ type=“java.lang.String“ />
    <form-property name=“passwd“ type=“java.lang.String“ />
    <form-property name=“passwd2″ type=“java.lang.String“ />
    <form-property name=“animal“ type=“java.lang.String“
      initial=“hippopotamus“ />
  </form-bean>
</form-beans>

Oproti původnímu formuláři jsme přidali položku animal (řekněme, že jde o formulář na sjezd chovatelů drobného zvířectva), na které demonstrujeme možnost naplnění položky formuláře výchozí hodnotou (v naší ukázce předpokládáme, že většina registrujících se uživatelů bude chovateli hrochů).

Samozřejmě, že atribut type může být v zásadě jakákoli smysluplná třída jazyka Java, přičemž „smysluplná“ v tomto případě znamená „obálková třída primitivního typu nebo String, nejlépe pak String“.

Vrátíme-li se ještě jednou k původnímu příkladu, vzpomeneme si, že v související akci jsme formulář získávali v parametru form metody execute, a k jeho položkám přistupovali pomocí přetypování tohoto parametru na naši RegistrationForm. Jak přistupovat k položkám formuláře reprezentovaného pomocí DynaActionForm demonstruje následující fragment kódu:

String login = (String)
  PropertyUtils.getSimpleProperty(registrationForm, „login“);

Zmíněná třída PropertyUtils se nachází v balíku org.apache.commons.beanutils z commons-beanutils.jar. Mimochodem, výše uvedeného postupu lze použít i pro získání příslušné „property“, ale není-li to nutné, doporučoval bych se tomu vyhnout.

Formuláře postavené na java.util.Map

Někdy mohou nastat situace, kdy nám i DynaActionForm přijde málo dynamická – například pokud jsme konfrontováni s požadavkem na formulář, který může obsahovat prakticky libovolný počet libovolných položek. I tomuto požadavku vychází Struts vstříc, ačkoli můžeme vést debaty o tom, nakolik se jedná o obezličku než o čisté řešení. Jako formulářovou třídu můžeme totiž použít i následující konstrukci:

public MapForm extends ActionForm {
  private final Map values = new HashMap();
  public void setValue(String key, Object value) {
    values.put(key, value);
  }
  public Object getValue(String key) {
    return values.get(key);
  }
}

V případě RegistrationForm jsme na JSP stránkách zobrazovali formulář pomocí značek jako <html:text property="login" />. Fígl s MapForm spočívá v tom, že tvůrci Struts umožnili odkazovat se i na metodu getValue (String), přestože oproti standardní get metodě JavaBean komponenty příjímá argument. Prostě na JSP stránce formuláře použijeme například následující:

<html:text property=“value(login)“ />

Prosté, leč účinné. A aby toho nebylo málo, analogicky – jen za použití hranatých závorek – si můžete vytvořit i obdobnou třídu, která namísto Map pracuje s List.

To si ale laskavý čtenář domyslí sám. Těším se na vaše komentáře pod článkem a omlouvám se za pauzu od posledního článku, nejen publikováním na Intervalu živ je člověk.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět