Skip to content

7. Przykład 05B – Nawigacja w formularzu wprowadzania danych

Analizujemy formularz zawierający kilka przycisków służących do przesłania (submit) wprowadzonych danych w celu wykonania określonej akcji.

 

7.1. Projekt NetBeans

Projekt NetBeans wygląda następująco:

  

Elementy projektu są następujące:

  • [DoSomething.JSP]: jedyny widok aplikacji, zawierający trzy przyciski nawigacyjne oraz link.
  • [DoSomething.java] i [DoSomethingElse.java]: dwie akcje projektu
  • [messages.properties]: plik z międzynarodowymi komunikatami
  • [struts.xml]: plik konfiguracyjny Struts 2

7.2. Configuration

Poniższy plik [struts.xml] konfiguruje aplikację:


<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
 <constant name="struts.custom.i18n.resources" value="messages" />
 <package name="actions" namespace="/actions" extends="struts-default">
    <action name="DoSomething" class="actions.DoSomething">
      <result name="success">/vues/DoSomething.JSP</result>
    </action>  
    <action name="DoSomethingElse" class="actions.DoSomethingElse">
      <result name="success">/vues/DoSomething.JSP</result>
    </action>  
  </package>
</struts>
  • Akcja [/actions/DoSomething] spowoduje instancjonowanie klasy [actions.DoSomething], a jej metoda execute zostanie wykonana domyślnie. To domyślne zachowanie można zmienić, jeśli parametry przekazane do akcji [Something] określą inną metodę. Niezależnie od tego, która metoda zostanie wykonana, musi ona zwrócić klucz nawigacyjny success, ponieważ tylko ten klucz został zdefiniowany. Następnie wyświetlony zostanie widok [DoSomething.JSP].
  • Konfiguracja akcji [/actions/DoSomethingElse] jest identyczna.

7.3. Plik komunikatów

Plik komunikatów [messages.properties] ma następującą treść:


formulaire.titre1=Actions et M\u00e9thodes
formulaire.titre2=Actions et M\u00e9thodes
formulaire.execute=DoSomething.execute
formulaire.action1=DoSomething.action1
formulaire.action2=DoSomethingElse.action2
formulaire.action3=DoSomething.action3

7.4. Widok [DoSomething.JSP]

Widok [DoSomething.JSP] wygląda następująco:

 

Jego kod jest następujący:


<%@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="formulaire.titre1"/></title>
  </head>
  <body>
    <h1><s:text name="formulaire.titre2"/></h1>
    <s:form action="DoSomething">
      <s:submit key="formulaire.execute"/>
      <s:submit key="formulaire.action1" method="action1"/>
      <s:submit key="formulaire.action2" action="DoSomethingElse" method="action2"/>
    </s:form>
    <s:url id="URL" action="DoSomething" method="action3"/>
    <s:a href="%{URL}"><s:text name="formulaire.action3"/></s:a>
  </body>
</html>
  • wiersz 11: formularz zostanie przesłany do akcji [DoSomething]. Nie oznacza to jednak koniecznie, że to właśnie ta akcja zostanie uruchomiona. Zależy to od przycisku submit użytego dla POST.
  • wiersz 12: przycisk submit nie określa ani akcji, ani metody. Zostanie wywołana akcja [DoSomething] określona przez tag <form>. Wykonana zostanie metoda zdefiniowana w pliku [struts.xml], czyli metoda execute.
  • wiersz 13: przycisk submit określa metodę. Zostanie wywołana akcja [DoSomething] określona przez tag <form>. Wykonana zostanie metoda action1.
  • wiersz 14: przycisk submit określa akcję i metodę. Zostanie wywołana akcja [DoSomethingElse]. Wykonaną metodą będzie metoda action2.
  • wiersze 16–17: odnośnik do akcji [DoSomething] i metody action3. Zostanie utworzona instancja akcji [DoSomething], a jej metoda action3 zostanie wykonana. W przeciwieństwie do przycisków submit, kliknięcie linku nie powoduje wywołania akcji POST, lecz akcji GET. Nie są zatem przesyłane żadne parametry.

Kod HTML wygenerowany przez ten kod, gdy wywołuje się URL [http://localhost:8084/exemple-05B/actions/DoSomething.action], wygląda następująco:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Actions et Méthodes</title>
  </head>
  <body>
    <h1>Actions et Méthodes</h1>
    <form ... action="/exemple-05B/actions/DoSomething.action" method="post">
...
       <input type="submit" ... name="formulaire.execute" value="DoSomething.execute"/>
...
       <input type="submit" ... name="method:action1" value="DoSomething.action1"/>
...
        <input type="submit" ... name="action:DoSomethingElse!action2" value="DoSomethingElse.action2"/>
...
    </form>
    ...
    <a href="<a href="view-source:http://localhost:8084/exemple-05B/actions/DoSomething%21action3.action">/exemple-05B/actions/DoSomething!action3.action</a>">DoSomething.action3</a>
  </body>
</html>
  • wiersz 9: tag form formularza HTML. Atrybut action wskazuje adres URL, na który zostaną wysłane parametry formularza. Ta akcja URL jest powiązana z akcją [DoSomething].
  • wiersze 11, 13, 15: atrybuty name przycisków zostaną przesłane do akcji docelowej przycisku submit. To właśnie pozwala Strutsowi określić, którą akcję należy zainicjować i którą metodę wykonać.
  • wiersz 13: atrybut name=method:action1 wskazuje, że należy wykonać metodę DoSomething.action1.
  • wiersz 15: atrybut name= action:DoSomethingElse!action2 wskazuje, że należy wykonać metodę DoSomethingElse.action2.
  • wiersz 11: atrybut name= formulaire.execute nie określa ani akcji, ani metody. W związku z tym zostanie wykonana metoda DoSomething.execute.
  • wiersz 19: link wyraźnie żąda wykonania metody DoSomething.action3

7.5. Akcje

Akcja [DoSomething] wygląda następująco:


package actions;

import com.opensymphony.xwork2.ActionSupport;

public class DoSomething extends ActionSupport {

  public DoSomething() {
    System.out.println("DoSomething");
  }

  @Override
  public String execute() {
    System.out.println("DoSomething.execute");
    return SUCCESS;
  }

  public String action1() {
    System.out.println("DoSomething.action1");
    return SUCCESS;
  }

  public String action3() {
    System.out.println("DoSomething.action3");
    return SUCCESS;
  }
}
  • Metody execute, action1 i action3 zapisują dane na konsoli serwera WWW i zwracają klucz nawigacyjny success.
  • wiersz 8: konstruktor również zapisuje informacje na konsoli serwera WWW

Różne wpisy na konsoli pozwalają ustalić, które metody są wykonywane podczas żądania.

Akcja [DoSomethingElse] przebiega podobnie:


package actions;

import com.opensymphony.xwork2.ActionSupport;

public class DoSomethingElse extends ActionSupport {

  public DoSomethingElse() {
    System.out.println("DoSomethingElse");
  }
  
  @Override
  public String execute() {
    System.out.println("DoSomethingElse.execute");
    return SUCCESS;
  }
  
  public String action2() {
    System.out.println("DoSomethingElse.action2");
    return SUCCESS;
  }
}

7.6. Testy

Testy wykazują następujące wyniki (na konsoli serwera WWW):

  • po kliknięciu przycisku [DoSomething.execute] instancja akcji [DoSomething] jest tworzona, a jej metoda execute wykonywana.
  • po kliknięciu przycisku [DoSomething.action1] tworzona jest instancja akcji [DoSomething] i wykonywana jest jej metoda action1.
  • Po kliknięciu przycisku [DoSomethingElse.action2] tworzona jest instancja akcji [DoSomethingElse] i wykonywana jest jej metoda action2.
  • Po kliknięciu linku [DoSomething.action3] tworzona jest instancja akcji [DoSomething] i wykonywana jest jej metoda action3.