Skip to content

16. Voorbeeld 13 – de context van een actie

Deze toepassing is bedoeld om te laten zien dat een actie toegang heeft tot:

  • de parameters van de aanvraag
  • de attributen van de verzoek
  • de attributen van de sessie van de gebruiker
 

16.1. Het NetBeans-project

Het NetBeans-project is als volgt:

  • in [1], de weergave [Context.JSP]
  • in [2], de actie [Action1.java] en het Struts-configuratiebestand [example.xml]

16.2. Configuration

De projectconfiguratie wordt uitgevoerd in [example.xml]:


<?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>
  <package name="example" namespace="/example" extends="struts-default">
    <action name="Action1" class="example.Action1">
      <result name="success">/example/Context.JSP</result>
    </action>
  </package>
</struts>
  • regel 8: de aanroep van URL [/example/Action1] zal leiden tot het instantiëren van de klasse [example.Action]. Aangezien er geen methode is opgegeven, wordt de methode execute uitgevoerd.
  • regel 9: er wordt slechts één sleutel geaccepteerd. De sleutel success leidt tot de weergave van de weergave [Context.JSP].

De vereenvoudigde architectuur voor de verwerking van een verzoek ziet er als volgt uit:

De aanvraag wordt verwerkt door twee onderdelen van de webapplicatie: de actie [Action1] [1] en de weergave [Context.JSP] [2]. Deze twee onderdelen hebben toegang tot verschillende soorten gegevens:

  • gegevens met het bereik Application, [3] en c.a.d. Deze gegevens zijn toegankelijk voor alle verzoeken van alle gebruikers. Ze zijn vrijwel altijd alleen-lezen. In deze gegevens is vaak de initiële configuratie van de applicatie te vinden. Hier hebben [Action1] en [Context.JSP] toegang tot deze gegevens.
  • Gegevens met het bereik Session, [4] en c.a.d. Deze gegevens zijn toegankelijk voor alle verzoeken van dezelfde gebruiker. Ze zijn zowel lees- als schrijfbaar. Hier zal [Action1] de sessie in lees-/schrijfmodus gebruiken, terwijl [Context.JSP] deze in leesmodus zal gebruiken.
  • Gegevens met het bereik Requête [5], die toegankelijk zijn voor alle elementen die de verzoek verwerken. Hier zal [Action1] gegevens in dit geheugen plaatsen en [Context.JSP] deze ophalen. Met de gegevens in het bereik ‘Verzoek’ kan een element N informatie doorgeven aan element N+1.
  • De parameters van de verzoekcode [6] die door de client zijn verzonden. Deze worden door de elementen die het verzoek verwerken uitsluitend in leesmodus gebruikt.

16.3. De actie [Action1]

De codeklasse [Action1] is als volgt:


package example;

import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import java.util.Set;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {

  // constructor zonder parameters
  public Action1() {
  }
  // Sessie, verzoek, parameters
  Map<String, Object> session;
  Map<String, Object> request;
  Map<String, String[]> parameters;

  @Override
  public String execute() {
    // lijst met parameters
    System.out.println("Paramètres...");
    Set<String> clés = parameters.keySet();
    for (String clé : clés) {
      for (String valeur : parameters.get(clé)) {
        System.out.println(String.format("[%s,%s]", clé, valeur));
      }
    }
    // sessie
    System.out.println("Session...");
    if (session.get("compteur") == null) {
      session.put("compteur", new Integer(0));
    }
    Integer compteur = (Integer) session.get("compteur");
    compteur = compteur + 1;
    session.put("compteur", compteur);
    System.out.println(String.format("compteur=%s", compteur));
    // verzoek
    request.put("info1", "information1");
    // pagina weergeven JSP
    return SUCCESS;
  }

  // sessie
  public void setSession(Map<String, Object> session) {
    this.session = session;
  }

  // verzoek
  public void setRequest(Map<String, Object> request) {
    this.request = request;
  }

  // parameters
  public void setParameters(Map<String, String[]> parameters) {
    this.parameters = parameters;
  }
}
  • regel 10: de klasse implementeert de volgende interfaces
    • SessionAware: om toegang te krijgen tot het woordenboek met sessieattributen (regel 16). Deze interface heeft slechts één methode, namelijk die op regel 46.
    • RequestAware: om toegang te krijgen tot het woordenboek met de attributen van de query (regel 17). Deze interface heeft slechts één methode, namelijk die op regel 51.
    • ParameterAware: om toegang te krijgen tot het woordenboek met de parameters van de query (regel 18). Merk op dat aan elke sleutel (de naam van de parameter) een array met waarden is gekoppeld. Dit is nodig om rekening te houden met invoervelden die meerdere waarden verzenden, zoals bijvoorbeeld een lijst met meervoudige selectie. De interface ParameterAware heeft slechts één methode, namelijk die op regel 56.
  • regel 21: de methode execute die wordt uitgevoerd wanneer de actie [Action1] wordt aangevraagd. Wanneer deze wordt uitgevoerd, hebben de interceptors hun werk gedaan:
    • de methode setParameters (regel 56) is aangeroepen en het parameters-woordenboek op regel 18 bevat alle parameters van de aanvraag.
    • de methode setSession (regel 46) is aangeroepen en het woordenboek ‘session’ op regel 16 bevat alle attributen van de sessie.
    • de methode setRequest (regel 51) is aangeroepen en het request-woordenboek op regel 17 bevat alle attributen van het verzoek.
  • regels 31-38: de waarde die bij de sleutel compteur hoort, wordt in de sessie geschreven
  • regels 32-34: de sleutel compteur wordt in de sessie opgezocht. Als deze daar niet wordt gevonden, wordt hij erin opgenomen met de gehele waarde 0.
  • regels 35-37: de sleutel compteur wordt in de sessie gezocht, de waarde ervan wordt verhoogd en vervolgens wordt de sleutel weer in de sessie opgeslagen.
  • regel 38: de waarde die aan de sleutel compteur is gekoppeld, wordt weergegeven. Aangezien de waarde bij elke aanvraag op de actie [Action1] wordt verhoogd, zou de waarde van de teller bij elke aanvraag moeten toenemen.
  • regel 40: er wordt in het woordenboek met verzoekattributen een attribuut ingevoegd met de sleutel info1 en de waarde information1. De attributen van een verzoek zijn iets anders dan de parameters ervan. De parameters worden door de client van de webapplicatie verzonden. De verzoekattributen maken de communicatie mogelijk tussen de verschillende onderdelen van de webapplicatie die het verzoek verwerken. Zo wordt, na de uitvoering van [Action1], de weergave [Context.JSP] getoond. We zullen zien dat deze in staat is om de verzoekattributen op te halen.
  • regel 42: de methode execute retourneert de sleutel succes.

16.4. Het berichtenbestand

Het bestand [messages.properties] ziet er als volgt uit:


Context.titre=Contexte de l''action
Context.message=Contexte de l''action
Context.parameters=Param\u00E8tres de l''action
Context.session=Elements de session
Context.request=Attributs de requ\u00EAte

16.5. De weergave [Context.JSP]

De weergave [Context.JSP] dient om het volgende weer te geven:

  • bepaalde parameters van de query
  • de waarde van de sleutel compteur in de sessie
  • de waarde van de sleutel info1 in de query

De code ervan is als volgt:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Context.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Context.message"/></h2>
    <h3><s:text name="Context.parameters"/></h3>
    <s:iterator value="#parameters['nom']" var="nom">
      nom : <s:property value="nom"/><br/>
    </s:iterator>
    <s:iterator value="#parameters['prenom']" var="prenom">
      prenom : <s:property value="prenom"/><br/>
    </s:iterator>
    <s:iterator value="#parameters['age']" var="age">
      âge : <s:property value="age"/><br/>
    </s:iterator>
    <h3><s:text name="Context.session"/></h3>
    compteur : <s:property value="#session['compteur']"/>
    <h3><s:text name="Context.request"/></h3>
    info1 : <s:property value="#request['info1']"/>
  </body>
</html>
  • regels 12-14: geven alle waarden weer die bij de parameter nom horen
  • regels 15-17: geven alle waarden weer die bij de parameter prenom horen
  • regels 18-20: geven alle waarden weer die bij de parameter age horen
  • regel 22: toont de waarde die hoort bij de sleutel compteur in de sessie
  • regel 24: geeft de waarde weer die bij de sleutel info1 in de query hoort

16.6. De tests

  • in [1] wordt Action1 opgevraagd zonder parameters
  • in [2], [Context.JSP] heeft geen parameters gevonden
  • in [3], [Context.JSP] is de sleutel compteur in de sessie gevonden
  • in [4], [Context.JSP] heeft de sleutel info1 in de query gevonden

Laten we nog een test doen:

  • in [1] wordt Action1 opgevraagd met parameters
  • in [2], [Context.JSP] geeft deze parameters weer
  • in [3], [Context.JSP] heeft de sleutel compteur in de sessie gevonden. De teller is inderdaad met 1 verhoogd, wat aantoont dat er daadwerkelijk opslag heeft plaatsgevonden tussen de twee verzoeken.
  • in [4] heeft [Context.JSP] de sleutel info1 in het verzoek gevonden

We herinneren ons dat de methode [Action1.execute] naar de console van de webserver schreef. Hier is een voorbeeld:

1
2
3
4
5
6
7
Paramètres...
[prenom,y]
[prenom,y2]
[age,z]
[nom,x]
Session...
compteur=2

16.7. Conclusion

Houd de volgende punten in gedachten:

  • om informatie op te slaan die door alle verzoeken van alle gebruikers moet worden gedeeld, gebruiken we het geheugen van de applicatie. We zullen hier binnenkort een voorbeeld van laten zien.
  • Om informatie op te slaan die door alle verzoeken van dezelfde gebruiker moet worden gedeeld, gebruiken we de sessie van die gebruiker.
  • Om informatie op te slaan die door alle elementen die een verzoek verwerken moet worden gedeeld, gebruiken we het geheugen van het verzoek.