8. Erstellen eines Plugins
Es ist möglich, Anwendungen zu erstellen, die als Plugins bezeichnet werden und beim Start einer Struts-Anwendung geladen sowie beim Herunterfahren wieder entladen werden. Dies ermöglicht in der Regel die Initialisierung beim Start der Anwendung und die Freigabe von Ressourcen beim Herunterfahren. Diese Vorgänge können auch durch eine Erweiterung der ActionServlet-Klasse des Controllers durchgeführt werden, wie es in der vorherigen Anwendung geschehen ist. Das Plugin stellt eine Alternative zu dieser Lösung dar. Ein Plugin kann eine komplexere Anwendung sein als eine einfache Umgebungsinitialisierung. Ein Beispiel hierfür haben wir in der Lektion gesehen, in der deklarative Validierungsregeln vorgestellt wurden. Ein Plugin wird in der Struts-Konfigurationsdatei deklariert. Das ValidatorPlugIn wurde in der Datei struts-config.xml der Anwendung, die es verwendete, wie folgt deklariert:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"
/>
</plug-in>
Wir werden nun eine Struts-Anwendung unter Verwendung eines Plugins beschreiben.
8.1. Konfiguration der Struts-Anwendung /plugin1
Wir schlagen vor, die Struts-Anwendung /plugin1 wie folgt zu konfigurieren:
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
Wir werden nicht näher auf diese Datei eingehen, da sie dem Standard entspricht.
struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<plug-in className="istia.st.struts.plugins.MyPlugin">
<set-property property="passwdFileName" value="data/passwd"/>
<set-property property="groupFileName" value="data/group"/>
</plug-in>
</struts-config>
Wir haben nur einen Abschnitt hinzugefügt, nämlich den für das Plugin. Die Attribute des hier verwendeten <plug-in>-Tags lauten wie folgt:
Name der Plugin-Klasse | |
ermöglicht die Initialisierung des Plugins mit (Schlüssel, Wert)-Paaren |
Der Zweck dieser Anwendung besteht darin, zu veranschaulichen, wie das Plugin seine Initialisierungsparameter abrufen und sie anderen Objekten zur Verfügung stellen kann, die denselben Anwendungskontext nutzen. Wir verwenden eine einfache JSP-Ansicht, um die Initialisierungswerte des Plugins anzuzeigen, was erklärt, warum die Konfigurationsdatei keine Aktion enthält.
8.2. Die Java-Klasse des Plugins
Eine Java-Klasse, die als Plugin für eine Struts-Anwendung dient, muss die Schnittstelle org.apache.struts.action.PlugIn implementieren. Diese Implementierung umfasst das Schreiben von zwei Methoden:
- public void init(ActionServlet servlet, ModuleConfig conf)
- public void destroy()
Wenn die Struts-Anwendung geladen wird, instanziiert ihr Controller alle in der Datei struts-config.xml deklarierten Plugins. Anschließend führt er für jedes einzelne die init-Methode aus. Innerhalb dieser Methode führt das Plugin seine Initialisierung durch. Hier lesen wir einfach die Initialisierungsparameter des Plugins ein und legen sie im Anwendungskontext ab, damit sie allen anderen Objekten in der Anwendung zur Verfügung stehen. Wenn die Anwendung entladen wird, führt der Controller für jedes der geladenen Plugins die Methode destroy aus. Dies ist der Zeitpunkt, um nicht mehr benötigte Ressourcen freizugeben. Hier haben wir nichts zu tun.
Der Klassencode lautet wie folgt:
package istia.st.struts.plugins;
import javax.servlet.ServletException;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.PlugInConfig;
public class MyPlugin implements PlugIn {
// method called when application context is deleted
public void destroy() {
}
// method called on initial creation of application context
public void init(ActionServlet servlet, ModuleConfig conf)
throws ServletException {
// class name of this object
String className=this.getClass().getName();
// plug-in list
PlugInConfig[] pluginConfigs = conf.findPlugInConfigs();
// explore plugins to find the right one
// which is named after this class
boolean trouvé=false;
for (int i = 0; ! trouvé && i < pluginConfigs.length; i++) {
// plugin name
String pluginClassName=pluginConfigs[i].getClassName();
// if it's not the right plugin, continue
if(! pluginClassName.equals(className)) continue;
// it's the right one - you memorize its properties in context
servlet.getServletContext().setAttribute("initialisations",pluginConfigs[i].getProperties());
trouvé=true;
}//for i
} //init
} //class
Bitte beachten Sie folgende Punkte:
- Die Methode init nimmt einen Parameter namens conf (vom Typ ModuleConfig) entgegen, der Zugriff auf den Inhalt der Datei struts-config.xml gewährt.
- Die Methode [ModuleConfig].findPlugInConfigs() ruft alle <plug-in>-Abschnitte aus der Struts-Konfigurationsdatei in Form eines Arrays von PlugInConfig-Objekten ab.
- Die Klasse PluginConfig repräsentiert einen <plug-in>-Abschnitt der Konfigurationsdatei. Die Methode [PlugInConfig].getProperties ermöglicht den Zugriff auf die <set-property>-Elemente des Abschnitts in Form eines java.util.Map-Wörterbuchs.
- Das Eigenschaften-Wörterbuch des Plugins wird im Anwendungskontext abgelegt.
- Da es mehrere Plugins geben kann, müssen wir dasjenige finden, das uns interessiert. Es ist dasjenige, das denselben Namen wie die ausgeführte Klasse trägt.
Hier haben wir uns dafür entschieden, das gesamte Wörterbuch im Kontext abzulegen. Wir hätten uns auch dafür entscheiden können, es zu verwenden. Der folgende Codeausschnitt veranschaulicht eine Möglichkeit, dies zu tun:
Map initialisations = pluginConfigs[i].getProperties();
// iterate over dictionary entries
Iterator entrées = initialisations.entrySet().iterator();
while (entrées.hasNext()) {
// retrieve current input (key,value)
Map.Entry entrée = (Map.Entry) entrées.next();
String clé = (String) entrée.getKey();
String valeur = (String) entrée.getValue();
// exploit (key,value)
//...
}
8.3. Der Code für die Ansicht infos.jsp
Die Ansicht infos.jsp ist für die Anzeige des Inhalts des Eigenschaftsverzeichnisses des Plugins zuständig, das im Anwendungskontext abgelegt wurde. Da die Ansicht infos.jsp Teil dieses Kontexts ist, hat sie Zugriff darauf. Ihr Code lautet wie folgt:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>Plugin</title>
</head>
<body>
<h3>Infos du plugin<br></h3>
<table border="1">
<tr>
<th>Clé</th><th>Valeur</th>
</tr>
<logic:iterate id="element" name="initialisations">
<tr>
<td><bean:write name="element" property="key"/></td>
<td><bean:write name="element" property="value"/></td>
</tr>
</logic:iterate>
</table>
</body>
</html>
Hinweise:
- Wir verwenden die Tag-Bibliotheken „struts-logic“ und „struts-bean“
- Das <logic:iterate>-Tag ermöglicht es uns, das Initialisierungswörterbuch anzuzeigen, das durch die init-Methode des Plugins in den Kontext gestellt wurde. Das name-Attribut gibt das Objekt an, über das iteriert werden soll. Dies sollte beispielsweise eine Sammlung, ein Iterator usw. sein. Das Objekt wird in allen Bereichen (Seite, Anfrage, Sitzung, Kontext) gesucht. Hier wird es im Kontextbereich gefunden. Der Parameter „id“ wird verwendet, um das aktuelle Element der Sammlung im Verlauf der Iteration zu benennen. Hier, innerhalb des Hauptteils des <logic:iterate>-Tags, steht „element“ für das aktuelle Element eines Wörterbuchs. Dies wird durch ein java.util.Map.Entry-Objekt dargestellt, das im Wesentlichen ein (Schlüssel, Wert)-Paar aus dem Wörterbuch ist.
- Im Hauptteil des <logic:iterate>-Tags zeigen wir (<bean:write>) den Inhalt des aktuellen Elements „element“ an. Dieses wird als Objekt mit zwei Eigenschaften behandelt: dem Schlüssel und dem Wert. Beide Eigenschaften werden angezeigt.
8.4. Bereitstellung
Der Anwendungskontext wird in der Konfigurationsdatei „server.xml“ von Tomcat definiert:
<Context path="/plugin11" reloadable="true" docBase="E:\data\serge\web\struts\plugins\1" />
Die Verzeichnisstruktur der Anwendung sieht wie folgt aus:
![]() ![]() | ![]() | ||
![]() | |||
8.5. Testen
Wir starten Tomcat und rufen die URL http://localhost:8080/plugin1/infos.jsp auf:

Wir stellen fest, dass die Ansicht infos.jsp über das Plugin erfolgreich auf die im Anwendungskontext gespeicherten Informationen zugegriffen hat.
8.6. Fazit
Wir haben gezeigt, dass eine Struts-Anwendung mithilfe eines Plugins initialisiert werden kann. Dies kann als Alternative zur Ableitung der ActionServlet-Klasse dienen, um das gleiche Ergebnis zu erzielen.



