All’interno di Spring 3 è stato notevolmente potenziato il sistema di validazione, portandolo a recepire la JSR-303 (che si occupa proprio di definire le specifiche del bean validator).

Link di Interesse

Prima di cominciare voglio presentare alcuni link molto utili che possono servire per la consultazione:

Utilizzo Base del Validation

Utilizzando ROO 1.0.2, di default ti permette di creare BEAN che utilizzino la JSR-303 e le specifiche di ejb 3.

Ad esempio è possibile avere il seguente bean:

public class Utente {
// Impone che il campo sia not null
@NotNull
private String nome;
// Il valora del campo deve seguire  il patter della espressione regolare
@Pattern(regexp=”[a-z]+”)
private String gruppo;
// il valore del campo deve seguire la espressione regolare standard per l’email
@email
private String email;
}

Questa impostazione del bean ci permette di utilizzare da subito il validation integrato in spring, in modo da eseguire un controllo immediato sulla consistenza dei campi del bean.
Ad esempio è possibile creare un controller del tipo:

@RequestMapping(value = “/utente”, method = RequestMethod.POST)

public String UtenteController.create(@Valid Utente utente, BindingResult result, ModelMap modelMap) {

if (utente == null) throw new IllegalArgumentException(“A utente is required”);

if (result.hasErrors()) {

modelMap.addAttribute(“utente”, utente);

……

……

return “utente/create”;

}

utente.persist();

return “redirect:/utente/” + utente.getIdUtente();

}

Questo esempio di controller utilizza l’annotation javax.validation.Valid “@Valid” che permette di verificare che l’oggetto relativo (Utente) inviato da un form ipotetico, segua le indicazioni definite all’interno del bean. l’esempio ci mostra come utilizzare da subito la validazione, ma purtroppo ha dei limiti legati al fatto che cosi com’è stato definito il bean può coprire solo una parte delle specifiche di bussiness.

Validatore Personalizzato

Per poter implementare un proprio validation è necessario:

1 – Definire all’interno dell’applicationContext.xml i bean che abilitano il validation personalizzato

<!–     Invokes Spring MVC @Controller methods –>

<bean class=”org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter”>

<property name=”webBindingInitializer”>

<!– Configures Spring MVC DataBinder instances –>

<bean class=”org.springframework.web.bind.support.ConfigurableWebBindingInitializer”>

<property name=”validator” ref=”validator” />

</bean>

</property>

</bean>

<!– Creates the JSR-303 Validator –>

<bean id=”validator” class=”com.springsource.roo.pizzashop.validation.UtenteValidator” />

2 – Creare la classe “UtenteValidator” (definita all’interno dell’applicationContext) che permette di sviluppare la nostra validazione personalizzata.

public class UtenteValidator implements Validator{

@Override

public boolean supports(Class clazz) {

return Utente.class.isAssignableFrom(clazz);

}

@Override

public void validate(Object target, Errors errors) {

System.out.println(“Sono dentro il validator”);

// Validazione del campo Utente.nome tramite le Utils di Validation

ValidationUtils.rejectIfEmptyOrWhitespace(errors, “nome”, “error.utente.vuoto”, “Il campo utente e’ richiesto”);

// Validazione personalizzata per l’oggetto utente ed le sue proprietà in

// questo modo posso implementare le logiche di bussiness come Utente utente = (Utente)target;

if( (utente.getNome().equals(“”)) && utente.getGruppo().equals(“”) ){

errors.rejectValue(“gruppo”, “error.utente.gruppo”);

}

}

}

All’interno della classe abbiamo fatto l’override di due metodi:

  • supports: dove posso specificare a quale classe associare il mi validator;
  • validate: dove implemento i vari controlli che devo eseguire sui campi, e le relative logiche.

Il nostro controller visto precedentemente deve cambiare nel seguente modo:

@RequestMapping(value = “/utente”, method = RequestMethod.POST)

public String UtenteController.create(@ModelAttribute(“utente”) Utente utente, BindingResult result, ModelMap modelMap) {

if (utente == null) throw new IllegalArgumentException(“A utente is required”);

// Chiamo il validatore per l’oggetto utente

validator.validate(utente, result);

if (result.hasErrors()) {

modelMap.addAttribute(“utente”, utente);

return “utente/create”;

}

utente.persist();

return “redirect:/utente/” + utente.get_id();

}

I cambiamenti più vistosi (segnati in grassetto) sono:

  • la presenza del @ModelAttribute al posto del @Valid, che permette di catturare l’oggetto inviato da un form senza però eseguire il validator integrato;
  • validator.validate: che permette di chiamare il validator personalizzato che abbiamo creato inviando l’oggetto da verificare

3 – La pagina con la quale comunicherà il nostro controller sarà composta nel seguente modo:

<spring:url value=”/utente” var=”form_url”/>

<form:form action=”${form_url}” method=”POST” modelAttribute=”utente”>

<form:errors cssClass=”errors” delimiter=”&lt;p/&gt;”/>

<div id=”roo_utente_nome”>

<label for=”_nome_id”>Nome:</label>

<form:input cssStyle=”width:250px” id=”_nome_id” maxlength=”30″ path=”nome” size=”0″/>

<br/>

<form:errors cssClass=”errors” id=”_nome_error_id” path=”nome”/>

</div>

<br/>

<div id=”roo_utente_gruppo”>

<label for=”_gruppo_id”>Gruppo:</label>

<form:input cssStyle=”width:250px” id=”_gruppo_id” maxlength=”30″ path=”gruppo” size=”0″/>

<br/>

<form:errors cssClass=”errors” id=”_gruppo_error_id” path=”gruppo”/>

</div>

<br/>

<div id=”roo_utente_email”>

<label for=”_id_email”>email:</label>

<form:input cssStyle=”width:250px” id=”_id_email” maxlength=”30″ path=”email” size=”0″/>

<br/>

<form:errors cssClass=”errors” id=”_email_error_id” path=”email”/>

</div>

<br/>

<div class=”submit” id=”roo_utente_submit”>

<input id=”proceed” type=”submit” value=”Salva”/>

</div>

</form:form>

La nostra pagina utilizza i tag di spring, quali:

  • form =  dove si definisce il bean che deve essere associato al form stesso;
  • form:input = il campo input che rappresenta una della proprietà del mio bean;
  • form:error = Questo tag è molto importante per la validazione, in quanto mostra a video la label di errore che viene viene generata dalla nostra classe di validazione.

Annunci