2010-09-14 14 views
40

Per i parametri di richiesta che rappresentano stringhe, numeri e valori booleani, il contenitore MVC Spring può associarli alle proprietà tipizzate fuori dalla scatola.Spring MVC - Binding a Date Field

Come si dispone del contenitore MVC di Spring per associare un parametro di richiesta che rappresenta una data?

A proposito, in che modo MVC Spring determina il tipo di un determinato parametro di richiesta?

Grazie!

risposta

62

In che modo il MVC Spring determina il tipo di un parametro di richiesta specificato?

La molla utilizza ServletRequestDataBinder per associare i suoi valori. Il processo può essere descritto come segue

/** 
    * Bundled Mock request 
    */ 
MockHttpServletRequest request = new MockHttpServletRequest(); 
request.addParameter("name", "Tom"); 
request.addParameter("age", "25"); 

/** 
    * Spring create a new command object before processing the request 
    * 
    * By calling <COMMAND_CLASS>.class.newInstance(); 
    */ 
Person person = new Person(); 

...

/** 
    * And Then with a ServletRequestDataBinder, it bind the submitted values 
    * 
    * It makes use of Java reflection To bind its values 
    */ 
ServletRequestDataBinder binder = ServletRequestDataBinder(person); 
binder.bind(request); 

Dietro le quinte, DataBinder istanze rende internamente uso di un'istanza BeanWrapperImpl che è responsabile per impostare i valori dell'oggetto comando. Con getPropertyType metodo, recupera il tipo di proprietà

Se si vede la richiesta presentata sopra (ovviamente, utilizzando un finto), Primavera chiamerà

BeanWrapperImpl beanWrapper = new BeanWrapperImpl(person); 

Clazz requiredType = beanWrapper.getPropertyType("name"); 

And Then

beanWrapper.convertIfNecessary("Tom", requiredType, methodParam) 

In che modo il contenitore MVC di Spring associa un parametro di richiesta che rappresenta una data?

Se si dispone di rappresentazione umana-friendly dei dati che ha bisogno di conversione speciale, è necessario registrare un PropertyEditor Per esempio, java.util.Date non sa cosa 13/09/2010 è, quindi dite Primavera

Primavera, convertire questa data human-friendly utilizzando il seguente PropertyEditor

binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { 
    public void setAsText(String value) { 
     try { 
      setValue(new SimpleDateFormat("dd/MM/yyyy").parse(value)); 
     } catch(ParseException e) { 
      setValue(null); 
     } 
    } 

    public String getAsText() { 
     return new SimpleDateFormat("dd/MM/yyyy").format((Date) getValue()); 
    }   

}); 

Quando si chiama il metodo convertIfNecessary, Primavera cerca qualsiasi registere d PropertyEditor che si occupa della conversione del valore presentato. Per registrare il PropertyEditor, è possibile

Primavera 3,0

@InitBinder 
public void binder(WebDataBinder binder) { 
    // as shown above 
} 

Vecchio stile della molla 2.x

@Override 
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) { 
    // as shown above 
} 
+0

Grazie mille. –

+1

Spring 2.5.x ha anche un @InitBinder: http://static.springsource.org/spring/docs/2.5.x/reference/mvc.html#mvc-ann-initbinder – Rihards

+2

Grazie perché questo sembra essere un risposta esauriente ma per i non esperti sarebbe davvero utile includere un semplice esempio pratico. – Marquez

30

In complemento alla risposta molto completa di Arthur: nel caso di un semplice Data campo, non è necessario implementare l'intero PropertyEditor. Si può semplicemente usare uno CustomDateEditor al quale si passa semplicemente il formato della data da utilizzare:

//put this in your Controller 
//(if you have a superclass for your controllers 
//and want to use the same date format throughout the app, put it there) 
@InitBinder 
private void dateBinder(WebDataBinder binder) { 
      //The date format to parse or output your dates 
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy"); 
      //Create a new CustomDateEditor 
    CustomDateEditor editor = new CustomDateEditor(dateFormat, true); 
      //Register it as custom editor for the Date type 
    binder.registerCustomEditor(Date.class, editor); 
} 
+0

L'aggiunta di alcuni commenti al tuo codice aiuterà l'OP a comprendere la tua proposta di risposta. Controlla questa [metaSO question] (http://meta.stackexchange.com/questions/7656/how-do-i-write-a-good-answer-to-a-question) e [Jon Skeet: Coding Blog] (http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx) su come dare una risposta corretta. – Yaroslav