Skip to content

6. Przykład 05 – Formularz wprowadzania danych

Na prostym przykładzie wprowadzimy pojęcie formularza wprowadzania danych.

6.1. Projekt NetBeans

W pliku [1] projekt:

  • widoki [Saisie.JSP], [Confirmation.JSP]
  • plik konfiguracyjny [struts.xml]
  • plik komunikatów [messages.properties]
  • akcja [Confirmer.java]

W [2] – strona wprowadzania danych

6.2. Configuration

Plik [struts.xml] ma następującą treść:


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
  <!-- internacjonalizacja -->
  <constant name="struts.custom.i18n.resources" value="messages" />
  <!-- pakiet domyślny -->
  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Saisir</param>
        <param name="namespace">/actions</param>
      </result>
    </action>
  </package>
  <!-- pakiet akcji -->
  <package name="actions" namespace="/actions" extends="struts-default">
    <action name="Saisir">
      <result name="success">/vues/Saisie.JSP</result>
    </action>
    <action name="Confirmer" class="actions.Confirmer">
      <result name="success">/vues/Confirmation.JSP</result>
    </action>  
  </package>
</struts>
  • wiersz 20: pakiet akcji URL /actions/Action.
  • wiersze 21–23: definiują akcję [Saisir]. Nie jest z nią powiązana żadna klasa. Odpowiedzią jest zawsze widok [/vues/Saisie.JSP]
  • wiersze 24–26: definiują akcję [Confirmer]. Przypisana jest do niej klasa [actions.Confirmer]. Odpowiedzią jest zawsze widok [/vues/Confirmation.JSP]

6.3. Akcja [Confirmer]

Jej kod jest następujący:


package actions;

import com.opensymphony.xwork2.ActionSupport;

public class Confirmer extends ActionSupport{
  
  // szablon
  private String nom;
  
  // metody pobierające i ustawiające

  public String getNom() {
    return nom;
  }

  public void setNom(String nom) {
    this.nom = nom;
  }
  
}

Klasa posiada tylko jedno pole, znajdujące się w wierszu 8 wraz z metodami get i set.

6.4. Plik komunikatów

Zawartość pliku [messages.properties] jest następująca:


saisie.texte=Formulaire de saisie
saisie.titre1=Saisie
saisie.titre2=Saisie
saisie.libelle=Tapez votre nom
saisie.valider=Valider
confirm.titre1=Confirmation
confirm.titre2=Confirmation
confirm.texte=Bonjour
confirm.retour=Retour au formulaire de saisie

Te klucze komunikatów są używane w obu widokach: [Saisie.JSP] i [Confirmation.JSP].

6.5. Widoki

6.5.1. Widok [Saisie.JSP]

Wygląda on następująco:

Jego kod źródłowy wygląda następująco:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="saisie.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="saisie.titre2"/></h1>
    <s:form action="Confirmer">
      <s:textfield key="saisie.libelle" name="nom"/>
      <s:submit key="saisie.valider" action="Confirmer"/>
    </s:form>
  </body>
</html>
  • wiersz 7: wyświetla komunikat o kluczu saisie.titre1 (Wprowadź) [1].
  • wiersz 10: wyświetla komunikat o kluczu saisie.titre2 (Wprowadź) [2].
  • wiersze 11, 14: tag <s:form> wprowadza formularz HTML. Wszystkie dane wprowadzone w tym formularzu zostaną wysłane na serwer WWW. Mówi się, że są to postées, ponieważ operacja HTTP, która ma miejsce podczas wysyłania danych na serwer, nazywa się POST. Wysyłane dane mają postać ciągu znaków param1=valeur1&param2=valeur2&... Z tym ciągiem znaków zetknęliśmy się już w punkcie 3.5 przykładu 02. W obu przypadkach ciąg parametrów jest przetwarzany w ten sam sposób przez Struts 2. Wartości valeuri parametrów parami są wstrzykiwane do wykonywanej akcji, do pól o nazwach identycznych z nazwami parametrów parami. Do kogo wysyłane są przesłane dane? Domyślnie do akcji, która wyświetliła formularz, w tym przypadku do akcji Saisir [5]. Można również użyć atrybutu action, aby wskazać inną akcję, w tym przypadku akcję [Confirmer].
  • wiersz 12: tag <s:textfield ...> wyświetla pole wprowadzania danych [3]. Jego atrybut key określa klucz etykiety, która ma być wyświetlana po lewej stronie pola wprowadzania danych. Etykieta jest zatem wyszukiwana w pliku [messages.properties]. Atrybut name to nazwa parametru, który zostanie przesłany. Wartością przypisaną do tego parametru będzie tekst wpisany w polu wprowadzania danych.
  • wiersz 13: tag <s:submit ...> wyświetla przycisk [4]. Jego atrybut key określa klucz etykiety, która ma być wyświetlona na przycisku. Etykieta jest zatem wyszukiwana w pliku [messages.properties]. Przycisk typu submit powoduje przesłanie formularza POST do akcji. Jak wspomniano powyżej, jest to akcja o nazwie [Confirmer] ze względu na atrybut action tagu <s:form>. Atrybut action tagu <s:submit> pozwala ewentualnie określić inną akcję. W tym przypadku przypisaliśmy akcję [Confirmer]. Przycisk ma domyślną nazwę parametru: action:nom_action, w tym przypadku action:Confirmer. Wartością powiązaną z tym parametrem jest etykieta przycisku. Ostatecznie ciąg parametrów wysyłany do akcji [Confirmer] po kliknięciu przez użytkownika przycisku [Valider] będzie wyglądał następująco:

?nom=xx&action:Confirmer=Valider.

gdzie xx to tekst wpisany przez użytkownika w polu wprowadzania danych.

6.5.2. Widok [Confirmation.JSP]

Wygląda to następująco:

Wpisujemy nazwę i zatwierdzamy stronę wprowadzania danych. Otrzymujemy wówczas odpowiedź [1], czyli widok [Confirmation.JSP]. Wartość URL wyświetlana w [2] pochodzi z akcji [Confirmer]. W powyższym przykładzie przesłano następujący ciąg znaków:

nom=bernard&action:Confirmer=Valider

Parametr action:Confirmer pozwala Struts 2 skierować żądanie do właściwej akcji, w tym przypadku do akcji [Confirmer]. Wartość parametru nom zostanie następnie wstrzyknięta do pola nom akcji [Confirmer].

Kod źródłowy akcji [Confirmation.JSP] wygląda następująco:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="confirm.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="confirm.titre2"/></h1>
    <s:text name="confirm.texte"/>&nbsp;
    <s:property value="nom"/> !
    <br/><br/>
    <a href="<s:url action="Saisir"/>"><s:text name="confirm.retour"/></a>
  </body>
</html>
  • wiersz 7: wyświetla nazwę klucza confirm.titre1 znalezioną w pliku komunikatów [1]
  • wiersz 10: wyświetla nazwę klucza confirm.titre2 znalezioną w pliku komunikatów [3]
  • wiersz 12: wyświetla właściwość nom akcji [Confirmer], która została wykonana.
  • wiersz 14: tworzy odnośnik do akcji [Saisir]. Tag <s:url>,, który już został napotkany, zostanie wygenerowany na podstawie tagów URL i [2] przeglądarki. Ścieżka będzie odpowiadać [2] http://localhost:8084/exemple-05/actions, a akcja – atrybutowi action, w tym przypadku Saisir. URL linku będzie zatem http://localhost:8084/exemple-05/actions/Saisir.action. Tekstem linku będzie nazwa powiązana z kluczem confirm.retour [4].

6.6. Testy

Oto dwa zapytania:

W [1] wpisujemy nazwę i zatwierdzamy. W [2] wyświetla się strona potwierdzenia.

W [3] klikamy link powrotny do formularza. W [4] widoczny jest wynik. Wszystko zostało wyjaśnione, z wyjątkiem przejścia z [3] do [4]. Dlaczego w [4] nie ma nazwy, którą wprowadziliśmy?

Link w [3] prowadzi do URL i [http://localhost:8084/exemple-05/actions/Saisir.action]. Akcja [Saisir] zostaje zatem wykonana. Przyjrzyjmy się jej konfiguracji w [struts.xml]:


<package name="actions" namespace="/actions" extends="struts-default">
    <action name="Saisir">
      <result name="success">/vues/Saisie.JSP</result>
    </action>
    <action name="Confirmer" class="actions.Confirmer">
      <result name="success">/vues/Confirmation.JSP</result>
    </action>  
</package>

Akcja [Saisir] nie jest powiązana z żadną akcją. W związku z tym natychmiast wyświetlany jest widok [Saisie.JSP]. Przyjrzyjmy się kodowi tego widoku:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title><s:text name="saisie.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="saisie.titre2"/></h1>
    <s:form>
      <s:textfield key="saisie.libelle" name="nom"/>
      <s:submit key="saisie.valider" action="Confirmer"/>
    </s:form>
  </body>
</html>

W wierszu 12 wyświetlane jest pole wprowadzania danych. Jego zawartość jest inicjowana za pomocą właściwości nom (name). Przypomnijmy sobie, co napisano powyżej na temat działania tagu <s:property>:

Tag <s:property name="właściwość"> pozwala zapisać wartość właściwości obiektu o nazwie ActionContext. W obiekcie tym znajdują się:

  1. właściwości klasy powiązanej z wykonaną akcją.
  2. atrybuty bieżącego żądania oznaczone jako <s:property name="#request['clé']">
  3. atrybuty sesji użytkownika oznaczone jako <s:property name="#session['clé']">
  4. atrybuty samej aplikacji oznaczone jako <s:property name="#application['clé']">
  5. parametry wysyłane przez przeglądarkę klienta oznaczone jako <s:property name="#parameters['clé']">
  6. notacja <s:property name="#attr['clé']"> wyświetla wartość obiektu wyszukanego kolejno na stronie, w zapytaniu, sesji i aplikacji.

Mamy tu do czynienia z przypadkiem 1. Akcja [Saisir] nie ma przypisanej klasy. Właściwość nom nie istnieje zatem. W polu wprowadzania danych wyświetlany jest wówczas pusty ciąg znaków.

Aby wyświetlić w [4] nazwę, która została wprowadzona w [1], wykorzystamy sesję użytkownika.