2011-01-13 19 views
5

Come ho capito, le istanze della classe azione di Struts2 possono (diversamente da Struts1) essere stateful, perché ogni GET o POST di un'azione crea una nuova istanza della classe di azione di supporto.Aiutami a capire meglio Struts2, convalida e azioni stateful

vedo anche che c'è uno standard linguaggio (Pattern?) Per fornire moduli di input (?): Lo stesso .jsp viene utilizzato come componente Vista di due diverse azioni, in questo modo:

<action name="showForm" class="defaultActionThatDoesNothingExceptReturnSuccess"> 
    <result name="success">inputForm.jsp</result> 
</action> 

<action name="validateAndProcessForm" class="realAction"> 
    <result name="input">inputForm.jsp</result> 
    <result name="success">formProcessed.jsp</result> 
</action> 

Il la prima azione mostra solo il modulo, senza convalidare l'input o elaborarlo. La forma in posti di .jsp all'azione secondo:

<s:form action="validateAndProcessForm" method="post"> 

e che la seconda azione convalida i campi/parametri inviati, tornando "input" se gli ingressi del modulo sono incomplete o non validi, o addirittura chiamando l'azione classe execute se gli input sono completi e validi, quindi elaborando il modulo e restituendo il (ad esempio) formProcessed.jsp che visualizza qualcosa del tipo "grazie per il vostro contributo!".

Quindi abbiamo questa sorta di linguaggio "steccato":

defaultAction-   -> realAction- 
      |   |  |  | 
      -> input.jsp- <---  -> success.jsp 

Questo è fatto in modo da visualizzare la prima volta input.jsp, convalide non sono chiamati (e così errori di validazione non sono mostrati), ma dopo aver fatto clic sul pulsante di invio su quel jsp, l'azione "reale" convaliderà l'input, eventualmente restituendo errori che invocano l'input non valido che verrà visualizzato da input.jsp.

Che ci riporta ad azioni stateful, non singleton; poiché l'azione è stateful e quindi non condivisa su GET o POST, e ogni istanza è istanziata solo per quel GET o POST, l'azione non ha modo di sapere se una determinata sessione ha "GETATO" la stessa pagina più volte. In modo da ottenere showForm.action sarà mai convalidare e geting volontà (errori e mostrare se i parametri non sono validi) sempre Convalida, anche se che ottiene è la prima volta che una particolare sessione ha "GETted" tale URL.

Ecco perché è necessario il "fence post": la prima azione solo per visualizzare il modulo, il secondo per acquisire l'input.

La mia comprensione è corretta? C'è un modo meno verboso per farlo, per non convalidare l'input sul GET iniziale, ma per convalidarlo sul POST, senza dover avere due azioni per ogni modulo?

+0

Non utilizzare azioni separate per visualizzare il modulo o elaborare il modulo. –

risposta

9

C'è un altro modo per eseguire ciò che vuoi senza il picchetto. L'intercettore di convalida, per impostazione predefinita, non attiva il metodo di input. È quindi possibile aggiornare lo struts.xml al seguente:

<action name="*MyForm" method="{1}" class="realAction"> 
    <result name="input">inputForm.jsp</result> 
    <result name="success">formProcessed.jsp</result> 
</action> 

Con questa impostazione, non occorre l'azione vuota a tutti. Quando si accede al modulo per la prima volta, si passa all'URL "inputMyForm" e l'azione del modulo viene semplicemente puntata su "MyForm". Il {1} ​​nel blocco del metodo significa solo che il framework chiamerà qualsiasi metodo corrisponda a * dal nome dell'azione. Se la corrispondenza * è vuota, per impostazione predefinita utilizza il metodo di esecuzione.In modo da ottenere i seguenti tipi di azioni:

  • inputMyForm sarebbe andato al metodo di input() della classe azione
  • MyForm sarebbe andato al metodo execute() della classe azione
  • executeMyForm sarebbe andato al metodo execute() della classe azione
  • customMethodNameMyForm sarebbe passare al metodo customMethodName() della classe azione

Dal momento che l'intercettore validatore esclude eventuali azioni che vanno al metodo di input, puoi impostare qualsiasi convalida che desideri per questa azione e la cercherà solo quando invii il modulo. Poiché ogni volta che si invia il modulo, si passa al metodo di esecuzione, la convalida verrà eseguita ogni volta che si invia il modulo.

Inoltre, se si sta estendendo la classe ActionSupport, quella classe già definisce il metodo input(), quindi non sarà nemmeno necessario modificare la classe di azioni per ottenere ciò.

0

È possibile fare le cose in modo diverso, ma diciamo che lasciate che struts2 gestisca tutte le richieste. Tutto ciò che gestisce è una "azione".

Non preoccuparti di GET o POST, sono solo due metodi diversi per inviare i dati a un'azione, se ci sono dei parametri (indipendentemente dal fatto che vengano ricevuti o impostati), struts2 cercherà di collocarli nella classe delle azioni (supponendo che ce ne sia uno). Se esiste un metodo di convalida (o un file xml di convalida correttamente denominato), la convalida verrà eseguita dopo l'impostazione delle proprietà della classe. Quindi viene chiamato il metodo execute() per la classe (supponendo che esista una classe). Dopo questo viene tipicamente reso un jsp che ha a sua disposizione tutti i dati pubblici nel metodo dell'azione.

Prendi la tua azione "showForm" ...è possibile ridurre il codice XML a:

<action name="showForm"> 
    <result>inputForm.jsp</result> 
</action> 

È possibile vedere che non è necessario definire una classe. Inoltre, il risultato predefinito è il successo, quindi non è necessario menzionarlo.

Quindi, quando pensiamo a hmtl, penseremmo in termini di pagine. Quando pensiamo ai montanti pensiamo in termini di azioni, devono solo essere complicati quanto necessario. Questo è il caso in cui è necessario mostrare un modulo, quindi è necessario un modulo di visualizzazione, se si desidera una pagina di visualizzazione che utilizza i dati del modulo, allora è necessaria un'azione "displayPage" che fa qualcosa con i dati del modulo.

Quindi pensa a ogni azione come inizia con un url> -----------> che termina con la data di ritorno (generalmente il rendering di un jsp). I trattini sono le parti opzionali che è possibile definire, ma se non lo fanno saranno sensibilmente predefiniti per voi. Per vedere quali funzionalità ti sono state fornite devi cercare in struts2-core-x.x.x.x.jar e visualizzare il contenuto di struts-default.xml che è dove "defaultStack" è definito. Viene chiamato ogni intercettore a sua volta, sapendo cosa offrono (e gli altri intercettori offrono) ti permettono di sapere cosa ottieni (non li guarderei troppo in profondità, ma so che sono lì così saprai per esempio che se hai bisogno di caricare un file il semplice fatto che l'intercettatore "fileUpload" sia nello stack predefinito dovrebbe essere abbastanza indicativo da dover essere integrato nelle funzionalità di caricamento dei file

Quindi non c'è una "falsa azione" al modulo di input: è una vera e propria azione, semplice: dopo aver imparato come definire pacchetti, azioni, azioni predefinite per un pacchetto e forse globalmente e imparare come definire un intercettore, dovresti dare un'occhiata alle convenzioni plug-in. Rende la vita molto più semplice!

0

La tua domanda ha un senso. il nostro modello è corretto, tuttavia:

  • come ha sottolineato Quaternion, c'è poca o nessuna "verbosità". Il tuo primo "showForm" è un fittizio "action mapping", la sua classe "do nothing" non ha bisogno di una particolare definizione di classe (l'ActionSupport predefinito è sufficiente).

  • ci sono altri possibili schemi; alcune persone potrebbero preferire l'idioma che stai sottolineando (e ha una lunga storia - ricordo di aver fatto alcune pagine CGI pelr in quel modo, secoli fa): usa un singolo url (e quindi una singola azione di mappatura) per i due "passi" "(mostra la forma iniziale ed elabora il modulo), indovinando all'interno del metodo di azione (o nel validatore) il passo corrente, forse controllando che alcuni parametri siano presenti (forse un campo nascosto) o forse discriminando POST/GET. In Struts2, preferisco l'altro modo, in generale.

BTW, chiamando le azioni Struts2 "stateful" è corretto solo se si undestand (si fa, a quanto pare) che quel 'stato' non sopravvive tra le richieste.

+0

Sì, stateful, non persistente. – tpdi

Problemi correlati