LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Apache Struts (4) - formuláře, modul Validator

Projdeme všechny typy formulářů a ukážeme si základní použití modulu Validator, který provádí kontrolu vstupních dat od uživatelů

25.3.2005 06:00 | Miroslav Holubec | Články autora | přečteno 9387×

Formuláře typu ActionForm

Téměř každá webová aplikace potřebuje získávat vstupy od uživatelů, např. uživatelská jména a hesla, uživatelské nastavení apod. HTML pro tyto potřeby poskytuje odpovídající prvky - textové pole, tlačítka, checkboxy a další. Struts všechen uživatelský vstup mapuje do vlastních formulářů, které jsou vždy podtřídou org.apache.struts.action.ActionForm a poskytují metody pro validaci vstupních dat, jejich předávání do akcí a jejich rušení. Jelikož je však ActionForm přímou součástí rámce, přičemž importuje balíky ze servletového API, není vhodné jeho přímé předávání do business vrstev. Obvyklé řešení je jeho zkopírování do DTO objektu pomocí BeanUtils a posléze již práce s daným DTO. Formulář Struts má následující rysy:

  • JavaBean - formulář má definované privátní členy a pro přístup k nim odpovídající veřejné metody
  • metoda reset() - ruší data ve formuláři
  • metoda validate() - kontroluje správnost dat

Jelikož Struts formuláře recyklují (pokud existuje stávající volná instance objektu, použije se), musí formulář definovat metodu reset(), která formulář vyčistí. Po tomto kroku dojde k naplnění formuláře vstupními daty, a posléze k jejich kontrole metodou validate(). Validace dat formuláře kontroluje správnost dat pouze na úrovni části VIEW, tedy že čísla jsou opravdu čísla, emailová adresa obsahuje zavináč apod. Následuje ukázka formuláře pro přihlašování uživatelů, v němž heslo musí být minimálně šestimístné číslo.

package cz.linuxsoft.web.struts.shop.forms;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;
import java.text.Format;
import java.text.NumberFormat;

public class LoginForm extends ActionForm {
    
    private String username = null;
    private String password = null;
    
    public void reset(ActionMapping      mapping,
                      HttpServletRequest request)
    {
        this.username = null;
        this.password = null;
    }
    
    public ActionErrors validate(ActionMapping      mapping, 
                                 HttpServletRequest request)
    {
        ActionErrors errors = new ActionErrors();
        if (username == null || username.length() < 1)
            errors.add("username",
	               new ActionMessage("errors.required", "User name"));
        if (password == null || password.length() < 1)
            errors.add("password",
	               new ActionMessage("errors.required", "Password"));
        else if (password.length() < 7)
            errors.add("password",
	               new ActionMessage("errors.minlength", "Password", "6"));
        else
        {
            try {
                Format format = NumberFormat.getNumberInstance();
                format.parseObject(password);
            } catch (Exception ex) {
                //heslo nelze převést na číslo
                errors.add("password",
		           new ActionMessage("errors.number", "Password"));
            }
        }
        return errors;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return this.username;
    }
    
    public String getPassword() {
        return this.password;
    }
}

Třída ActionErrors poskytuje účinný mechanismus předávání chybových zpráv zpět na stránku JSP, konkrétně do tagu <html:errors />. Jednotlivé zprávy se do ní přidávají metodou add(String klíč, ActionMessage zpráva), kde ActionMessage obsahuje sadu předdefinovaných konstruktorů, ve kterých první parametr představuje klíč ze souborů zdrojových svazků zpráv (MessagesResources) a další parametry jsou hodnoty předávané do klíče. Tímto dokáži účinně používat stávající položky zpráv a nemusím pro každou chybějící položku vytvářet vlastní zprávu. Odpovídající část z anglického souboru zdrojových svazků vypadá následovně:

errors.minlength={0} can not be less than {1} characters.
errors.required={0} is required.
errors.number={0} must be a number.

A k tomu ještě odpovídající konfigurační soubor Struts, pokud bychom ve formuláři nedefinovali metodu validate, parametr validate akce bychom změnili na false.

<form-beans>
  <form-bean
    name="loginForm"
    type="cz.linuxsoft.web.struts.shop.forms.LoginForm" />
</form-beans>
<action-mappings>
  <action
    path="/login"
    type="cz.linuxsoft.web.struts.shop.actions.LoginAction"
    name="loginForm"
    scope="request"
    input="/pages/login.jsp"
    validate="true">
      <forward name="success" path="/pages/welcome.jsp" />
  </action>
</action-mappings>

Formuláře typu DynaActionForm

Přes výhody, které nám přináší definování ActionFormů, existují i značné nevýhody tohoto řešení. Především v projektu vzniká značný počet jednoduchých tříd, které jenom kopírují DTO objekty. Dalším neduhem je, že ActionForm je svázán s HTML stránkou, jakákoliv její změna se tedy musí projevit i v této třídě. Proto se ve Struts v1.1 objevuje nový formulář dynamického typu, a to třída org.apache.struts.action.DynaActionForm. Celý formulář i s členy se definuje v konfiguračním souboru Struts, jak jsme již viděli v předminulém díle. Samozřejmě díky dynamickému charakteru tohoto formuláře nyní nelze provádět kontrolu dat metodou validate(), zde nastupuje modul Validator, který popíši dále. Formulář z minulé kapitoly by tedy vypadal takto:

<form-beans>
  <form-bean
    name="loginForm" 
    type="org.apache.struts.action.DynaActionForm">
      <form-property
        name="username"
        type="java.lang.String" />
      <form-property
        name="password"
        type="java.lang.Integer" />
  </form-bean>
</form-beans>

Formuláře typu LazyValidatorForm

Speciálním typem formuláře, který se objevuje od Struts v1.2.6 (zatím pouze development verze), je LazyValidatorForm. Tento formulář využívá nové třídy LazyBean, která jakožto součást BeanUtils, představuje "nafukovací" beanu, vytvářející si členy pouhým voláním metody set. Vlastností tohoto formuláře tedy je, že není nutné definovat žádné členy, vytvoří se automaticky za běhu přímo ze vstupních dat. Definice formuláře tedy vypadá takto:

<form-beans>
  <form-bean
    name="loginForm"
    type="org.apache.struts.validator.LazyValidatorForm" />
</form-beans>

Modul Validator

Jak jsme si již mohli všimnout, kontrolu uživatelských vstupů můžeme provádět přímo v potomcích ActionFormu. Tato možnost má však dost nevýhod, především dochází k silné opakovatelnosti kódu. Proto vznikl modul Validator, jenž přesouvá veškerou kontrolní logiku do speciálních xml souborů, přičemž přichází se spoustou již vytvořených standartních pravidel kontroly a zároveň nám dává možnost vytvořit vlastní pravidla založené na regulárních výrazech. Pokud chceme tento modul použít, musíme ho uvést do konfigurace Struts v části plugin. Následně všechny formuláře typu DynaActionForm, které chceme validovat, změníme na typ org.apache.struts.validator.DynaValidatorForm, to samé provedeme u formulářů typu ActionForm, kde změníme rodiče třídy na org.apache.struts.validator.ValidatorForm.

<form-beans>
  <form-bean
    name="loginForm"
    type="org.apache.struts.validator.DynaValidatorForm">
    <form-property
      name="username"
      type="java.lang.String" />
    <form-property
      name="password"
      type="java.lang.String" />
  </form-bean>
</form-beans>

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
  <set-property
    property="pathnames"
    value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml" />
</plug-in>

Soubor validator-rules.xml obsahuje již zmiňované předdefinované pravidla, validation.xml je určen pro naše nastavení. Jednoduchá validace pro předchozí příklady by tedy odpovídala následujícímu souboru:

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

<!DOCTYPE form-validation PUBLIC
 "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
 "http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">

<form-validation>
  <formset>
  
    <!-- jméno formuláře z konfigurace Struts -->
    <form name="loginForm">
    
      <!-- člen username je vyžadován -->
      <field property="username" depends="required">
        <!-- klíč z MessageResources -->
        <arg0 key="login.username"/>
      </field>
      
      <!-- člen password je vyžadován, musí to být číslo a mít minimální délku -->
      <field property="password" depends="required,integer,minlength">
        <!-- klíč z MessageResources -->
        <arg0 key="login.password"/>
        <!-- minimální délka, bere se z proměnných -->
        <arg1 name="minlength" key="${var:minlength}" resource="false"/>
        <!-- definice proměnných -->
	<var>
          <!-- proměnná pro minimální délku -->
	  <var-name>minlength</var-name>
	  <var-value>5</var-value>
	</var>
       </field>
       
    </form>
    
  </formset>
</form-validation>

Vidíme, že musíme definovat jednotlivé položky ve formuláři, přičemž pro každou položku je definován seznam pravidel parametrem depends. Argumenty zprávy jsou předávány podobně jako u ActionFormu, my pouze definujeme argumenty, které budou předány do hodnoty klíče. Pro položku můžeme definovat i seznam proměnných, v našem případě se jednalo o definici minimální délky řetězce. Validaci uživatelských vstupů můžeme rozdělit na validaci dat na serveru, což je standartní postup, a na kontrolu javascriptem, což je další možnost tohoto modulu. Pro standartní serverovou validaci není třeba nijak upravovat stávající jsp soubory, avšak při použití javascriptu je potřeba provést drobné změny. Nejprve si vytvoříme stránku javascript/static.jsp se statickou částí javascriptového kódu. Tento postup je vhodný vzhledem k poměru velikostí staticky a dynamicky generovaného kódu, přičemž při umístění statického javascriptu do speciálního souboru prohlížeč používá vyrovnávací paměť.

<%@ taglib uri="/tags/struts-html" prefix="html" %>

<html:javascript dynamicJavascript="false" staticJavascript="true" />

Následuje upravený soubor login.jsp, tučně jsou vyznačeny změny.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<%@ page contentType="text/html" %>
<%@ page pageEncoding="UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<html:xhtml />
<html:html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <title><bean:message key="login.title" /></title>
      <link
        rel="stylesheet"
	type="text/css" 
	href="<html:rewrite page="/theme/style.css" />">
      <html:javascript
        formName="loginForm"
	dynamicJavascript="true"
	staticJavascript="false"
	cdata="false"/>
      <script
        type="text/javascript"
	src="<html:rewrite page="/javascript/static.jsp" />">
      </script>
  </head>
    <body>
        <h1><bean:message key="login.title" /></h1>
        <div class="errors">
        <html:errors />
        <br /><br />
        </div>
        <html:form
	  action="/login"
	  method="post"
	  onsubmit="return validateLoginForm(this);">
        <table>
            <tr>
	       <td><bean:message key="login.username" /></td>
	       <td>:</td>
	       <td><html:text property="username" value="" /></td>
            </tr>
            <tr>
	       <td><bean:message key="login.password" /></td>
	       <td>:</td>
	       <td><html:password property="password" value="" /></td>
	    </tr>
        </table>
        <p>
	  <html:submit>
	    <bean:message key="login.submit" />
	  </html:submit>
	</p>
        </html:form>
    </body>
</html:html>

Příště

Tímto jsme si probrali základní typy formulářů používaných ve Struts a seznámili se s velice užitečným modulem Validator. Příště probereme jeho rozšířené možnosti včetně definice vlastních kontrolních pravidel.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

24.5.2013 6:42 /MaReK Olšavský
V rodině Arduina je nový přírůstek, Arduino Yún („Yún“ je čínsky „mrak“). Nové Arduino je nejen první s GNU/Linuxem, ale nabízí i WiFi konektivitu.
Přidat komentář

24.5.2013 6:42 /MaReK Olšavský
Na stránkách OMG! Ubuntu! vyšel krátký rozhovor s Markem Shuttleworthem. Tématy jsou Mir, Unity 8, budoucnost Ubuntu Touch, ale neunikl ani otázce na Windows 8.
Přidat komentář

23.5.2013 6:20 /MaReK Olšavský
Lektoři, kteří používají e-learning, se již nejspíše setkali s platformou Moodle, jejíž vývojáři vydali verzi 2.5 populární platformy. Vedle několika stovek drobných vylepšení přibyly i novinky v mobilním přístupu, podpora twitterovského Bootstrapu pro témata, nebo instalace pluginů přes administrátorskou část webového rozhraní.
Přidat komentář

23.5.2013 6:20 /MaReK Olšavský
Nová distribuce Pidora by měla zajímat Fedoristy, kteří mají Raspberry-Pi, jelikož je optimalizovaným spinem právě pro tuto platformu. Novinky Pidory shrnul Rick Lehrbaum .
Přidat komentář

23.5.2013 6:20 /MaReK Olšavský
Krátce po vydání Debianu 7 vyšel i Debian GNU/Hurd 2013. Jádro GNU/Hurd se vyvíjí delší dobu, než Linux, ale zatím je spíše zajímavostí, protože jádro Linux se etablovalo u velkých společností a změna kurzu je více než nepravděpodobná.
Přidat komentář

22.5.2013 6:46 /MaReK Olšavský
Svobodný software ve státní sféře nejsou jen vítězství, ale i mýty a pověry, které jej vylučují z výběru. 5 nejčastějších hloupostí o F/L/OSS zkritizoval Adam Firestone na stránkách OpenSource.com. Nesetkáváme se s podobnými argumenty i při snaze prosadit svobodný software ve firmách a u soukromých osob?
Přidat komentář

22.5.2013 6:46 /MaReK Olšavský
Embedovatelná databáze SQLite byla vydána ve verzi 3.7.17, která nabízí větší rychlost (v některých úlohách až dvojnásobnou), opravy několika chyb, nebo vylepšení možností nahrávání rozšíření. O SQLite se píše výrazně méně, než o konkurenci, ale velmi pravděpodobně jde o nejčastěji nasazené řešení, díky mnoha aplikacím.
Přidat komentář

22.5.2013 6:45 /MaReK Olšavský
14. května 2013 IBM oznámila konec vývoje Lotus SmartSuite , Lotus Organizer a Lotus 1-2-3, balíků aplikací, jež byly považovány za špičku v oboru. Krátký nekrolog za legendární Lotus 1-2-3, který byl vyvíjen 30 let, sepsal Steven J. Vaughan-Nichols.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.5.2013 17:55 / Martin Kumst
Re: zaheslování bash scriptu nebo složky

18.5.2013 7:44 / ---
Re: Prosím o pomoc či radu

15.5.2013 19:21 / Filip Vaněček
Cesty k souborům při používání coolurl

13.5.2013 6:50 / Radim Kolář
Zabbix

8.5.2013 6:07 / MaReK Olšavský
Web Upd8

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2013) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze | zákony online