Tu sei qui

Validazione in Parancoe.

Questo è il primo di una serie di post in cui parlerò di quello che sto facendo all'interno del progetto open source Parancoe.

Parancoe è un'idea che è nata all'interno del Jug Padova per la realizzazione di applicazioni web in Java, se siete interessati o volete partecipare, andate qua.

Uno dei problemi da risolvere è quello della gestione della validazione degli attributi di una classe (ad esempio presenza, lunghezza, ...).

Il problema della validazione

Andando ad analizzare più in dettaglio il problema, il meccanismo di validazione ha i seguenti requisiti:

  • deve essere di facile utilizzo per lo sviluppatore: data la classe A non deve essere obbligatorio scrivere la classe A_val che ne faccia la validazione.
  • deve comportare poca (o nulla) configurazione (sto parlando di file XML).
  • dovrebbe essere facilmente integrabile con il modulo di gestione della vista realizzato con Spring MVC.
  • deve essere (per il momento) lato server.

Validazione in Spring MVC.

Siccome uno dei requisiti è l'integrazione con la parte di presentazione, fatta con Spring MVC, chiarisco qui brevemente come funziona il meccanismo di validazione in questa libreria.

Supponiamo di avere una classe Person che contiene una serie di attributi, come il nome è il cognome e supponiamo di voler validare tale classe.

La classe sarà associata ad una form di inserimento e ad un controller che si occupa della
gestione della comunicazione tra model e view.

Spring MVC mette a disposizione l'interfaccia Validator, che fornisce un meccanismo di validazione.

Implementando tale interfaccia in una classe, ad esempio PersonValidator, possiamo in tale classe inserire le nostre regole di validazione.

Definendo tale classe nel file di configurazione della nostra web application possiamo associarla a Person ottenendo due cose:

  1. nel controller: viene iniettato il vettore di errori trovati dalla classe personValidator;
  2. nella view: nella jsp possiamo presentare gli errori tramite il tag: <form:errors />

Riassumendo, i passi da compiere sono:

  1. definire una classe che implementa Validator nella quale fare la validazione;
  2. definire nel file <nomecontroller>-servlet.xml il bean che rappresenta la classe definita in 1

    id="personValidator"
    class="org.parancoe.basicWebApp.po.PersonValidator"/>
  3. nel file di configurazione di 2 associare la classe di validazione alla classe validata:

    name="/people/edit.form"
    id="peopleEditController"
    class="org.parancoe.basicWebApp.controllers.PeopleEditController"
    parent="abstractController"> name="commandClass"
    value="org.parancoe.basicWebApp.po.Person"/>
    name="commandName"
    value="person"/>
    name="formView"
    value="people/edit"/>
    name="successView"
    value="redirect:list.html"/>
    ref="personValidator"/>


Questi passi vanno compiuti per ogni classe che deve essere validata.

Springmodules Validation


La soluzione al problema che sto analizzando prevede l'uso della libreria Springmodules.

La libreria Springmodules, mette a disposizione una serie di moduli a corredo del framework Spring.

Uno di questi è spring-modules-validation. Tale modulo fornisce un meccanismo di validazione che sfrutta le annotation e consente di dover scrivere pochissimo codice di configurazione.

Considerando la classe Person, possiamo definire la validazione direttamente sui field della stessa:

import org.springmodules.validation.bean.conf.
loader.annotation.handler.Length;
import org.springmodules.validation.bean.conf.
loader.annotation.handler.NotBlank;

public class Person {

@NotBlank
@Length(min=2,max=10)
private String firstName;

@NotBlank
@Length(min=2,max=20)
private String lastName;

@DateInThePast
private Date birthDate;

}

Le tre annotazioni definite permettono di controllare che:

  • Il field non sia blank (@NotBlank)
  • La lunghezza del field sia compresa tra due valori (@Length)
  • La data inserita sia antecedente alla data di sistema (@DateInThePast)

Non è stato dunque necessario definire una specifica classe di validazione, la classe che compie la validazione, cioè quella che si andrà a leggere le annotazioni presenti in Person, si chiama BeanValidator.

Per configurarla dovremo fare due cose:

  1. Definire il bean in <nomecontroller>-servlet.xml:

    id="validator"
    class="BeanValidator">

    name="configurationLoader"
    ref="configurationLoader"/>

    id="configurationLoader"
    class="AnnotationlBeanValidationConfigurationLoader" />


  2. Associare il bean alla classe Person:

    name="/people/edit.form"
    id="peopleEditController"
    class="org.parancoe.basicWebApp.controllers.PeopleEditController"
    parent="abstractController"> name="validator"
    ref="beanValidator"/>

BeanValidator implementa l'interfaccia Validator di Spring, quindi si integra perfettamente con il meccanismo di segnalazione degli errori di Spring MVC.

Inoltre definisce già una serie di regole di validazioni e permette di crearne di custom.

Inoltre permette di usare i resource bundle tramite alcune convenzioni sui nomi, ad esempio nel caso di Person il resource bundle inglese sarà:


Person.firstName[not.blank]=First Name is required
Person.lastName[not.blank]=Last Name is required

Alla regola NotBlank viene assegnato di default l'id not.blank.
Per particolareggiare il messaggio per i campi, li si qualifica con il nome della classe seguito dal nome del campo.

Per una trattazione più estesa delle proprietà di BeanValidator, rimando alla documentazione ufficiale.

Commenti

Mi pare che la validazione cosi' come proposta qui sia molto legata alla view... non sarebbe piu' senstato collegarla al model, visto che stiamo parlando di dati?

??????? Surprised

De cossa che xeo drio parlare!

Voialtri ed il vostro Java....

Ma se' proprio bravi pero'!

Surprised

mah ...java è alla portata di tutti, non servono prerequisiti. La laurea in ingegneria di certo è sprecata per scrivere codice java...ma d'altronde non ci sono altri lavori.

Secondo me la conoscenza di java non basta!
Me ne sono accorto partecipando al progetto parancoe: passo le notti a studiarmi tool e librerie... e non risco mai a portarmi in pari Cry

La laurea in ingegneria è sprecata/inadeguata per il mercato italiano dell'informatica.

Non ti serve a gran chè la teoria dell'NP-completezza, mentre sarebbe stato più utile un corso di ingegneria del software e uno avanzato di basi di dati.

Grande Andrea ti bacio!!!!

Quoto e rilancio con un corso di automazione industriale serio... NON volevo fare il programmatore... Eppure e' una percentuale rilevantissima dela mia gioranta lavorativa...

Frown

In realtà la validazione viene messa nella stessa classe dalla quale verrà gestita la persistenza: la classe Person su cui viene fatta la validazione è la stessa in cui viene dichiarata la persistenza (@javax.persistence.Entity())

 

 

Si', ma poi il binding lo fai con la forms che serve a immettere/modificare i dati. Se piu' form modificano la classe persistente, devono essere tutti citati nell'XML.
 
Quello che intendevo io era legare la validazione al modello di dati della classe, in modo che venga validata a ogni modifica e prima del salvataggio su db. In questo senso slegherei la validazione dalla view (le form non sono piu' menzionate nell'xml) e la legherei solo al model. Tutte le attivitia' di modifica/valorizzazione degli attributi della classe sarebbero automaticamente soggette a validazione.

In teoria, per come è stato pensato parancoe, ci sarà al più una form html associata alla classe, quindi il problema non si pone. Parancoe non vuole essere il framework che va bene per tutte le situazioni, nè vuole adottare rigorosamente principi di separation of concerns e/o modularità, ma bensì sempligficare lo sviluppo di applicazioni web che si adattano al 80-90% dei casi, soprattutto per semplici applicazioni web. Di framework che fanno tutto ce ne sono anche troppi, perchè inventarne un altro?. L'idea di dover scrivere un solo bean con criteri di validazione e persistenza annidati, anzichè dover scrivere bean, actionform, struts-validation, etc...beh secondo me è una ficata. Il tutto IMHO.

>scrivere un solo bean con criteri di validazione e persistenza annidati...

Volevo dire annotati.

Domande sulla la soluzione basata su spring-modules:
1) la configurazione al punto 1 e' comune, non va ripetuta per ogni classe soggetta a validazione, vero?
2) la configurazone al punto 2 dipende dall'implementazione di Person in qualche forma? potremmo pensare di autogenerarla?

>2) la configurazone al punto 2 dipende dall'implementazione di Person in qualche forma? potremmo pensare di autogenerarla?

Si dobbiamo fare una configurazione per ogni bean, sarebbe una bella cosa riuscire ad evitare questa configurazione, magari adottando una naming convention.

Stiamo attenti con le convenzioni sui nomi.
Bisognerebbe prevedere un meccanismo per verificare che siano rispettate a compile-time.

In questi giorni sono stato davvero infognato, non sono riuscito a seguire il thread. Comunque:

mariano: per il punto 1) sì, la configurazione è comune quindi la sipotrebbe piazzare su parancoeBase.xml

enrico: la configurazione con naming convention che suggerivi al punto 2) la si può discutere. Però la mia conoscenza di spring e AOP è abbastanza scarsa ancora...

Ma tosatti, non ste' drogarve... Non capisco molto di quello che scrivete, il javanese e' proprio complesso..... Almeno per me che non conosco un'ostia di Java.

Foot in mouth

Aggiungi un commento

About This Site

Questo sito pubblica i propri contenuti con licenza Creative Commons.
Per maggiori informazioni andate qua.
Per contattarmi: Scrivimi!
Questo sito è gratuito, e non usa alcun tipo di pubblicità.
Se mi vuoi aiutare a tenerlo vivo, se hai trovato qualcosa di utile, oppure se sei Bill Gates e non sai più dove buttare i soldi, prova a pensare ad una donazione:

Cool stuff

feed rss feed dei commenti gtrev on feedburner cocomment enabled on this site gtrev on technorati creative commons license Get Firefox! Dilbert: striscia quotidiana The Ubuntu Counter Project - user number # 9630 le mie foto su flickr i miei link su del.icio.us i miei link su stumbleupon View Andrea Nasato's profile on LinkedIn gtrev on twitter

Built with

Drupal cms Apache web server Php 4 mysql dbms

Upcoming events

gtrev@parancoe calendar

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer