Kurzanleitung um eine Seite mit Struts und Spring zu erstellen.
Ziel ist es eine URL foo.do aufzulösen und eine JSP aufzurufen, wobei die Inhalte der JSP über eine extra Transformationsklasse populiert werden sollen. Zusätzlich soll ein URL-Parameter ausgewertet werden. Hierbei handelt es sich um eine spezifische Beschreibung einer bestehenden Ausgangskonfiguration und ist nicht allgemein anwendbar.
Die Testseite liegt in einem Unterverzeichnis des webapp/tpl-Verzeichnisses: webapp/tpl/reports/berichtsAbo.jsp
Auf einer x-beliebigen Seite wird der Link eingefügt:
<html:link page="/reports/abo.do?status=new">Link</html:link>
In der Datei struts-action.xml wird die URL aufgelöst und eine Actionklasse zugewiesen:
<bean name="/reports/abo"
class="packageX.ReportsAboAction"
parent="displayOnlyAction">
<property name="transformationRegistry" ref="transformationRegistry" />
</bean>
Die Klasse TransformationRegistry wird in der ReportsAboAction benötigt und wird zur Laufzeit via Dependency Injection zugeordnet. Zusätzlich erbt die Klasse von DipsplayOnlyAction.
Der Formdeskriptor ReportsAbo zur Action sieht wie folgt aus:
:extends de.sci.commons.web.struts.PersistableForm
emailadresse "Email-Adresse" email
status "Status" opt
Daraus wird eine Formbeanklasse ReportsAboForm erzeugt, welche Getter/Setter Methoden für die Attribute bereitstellt.
In der Klasse ReportsAboAction.java wird zunächst die Form angegeben die verwendet werden und die ein Pfad zur JSP Datei der via Tiles aufgelöst wird:
/**
* Reports Abo Action.
* @struts.action path = "/reports/abo" name = "reportsAboForm" scope = "session"
* @struts.action-forward name = "show" path = "reports.abo"
*/
In der Datei tiles-defs.xml wird der Pfad aufgelöst und einer konkreten JSP-Datei zugewiesen:
<definition name="reports.abo" extends="main">
<put name="title" value="Bericht abonnieren" />
<put name="body" value="/tpl/reports/berichtAbo.jsp"/>
</definition>
Die Transformationsklasse ReportsAboTF soll Werte in die Formbean schreiben und lesen. In der Datei transformation.xml werden die Transformationsklassen angegeben und über eine TransformationRegistry registriert.
<bean id="reportsAboTF"
class="transformation.ReportsAboTF">
</bean>
<bean id="transformationRegistry"
class="transformation.TransformationRegistry">
<property name="transformations">
<set>
<ref local="reportsAboTF" />
</set>
</property>
</bean>
Im Konstruktor der Transformationsklasse ReportsAboTF werden sowohl die Formbean-Klasse als auch die Domainklasse angegeben:
public ReportsAboTF() {
setDomainObjectClass(ReportsAbo.class);
setFormBeanClass(ReportsAboForm.class);
}
Diese Klasse hat eine Methode populateFormBean in der die Domainobjektattribute in die Formbeanattribute geschrieben werden:
public void populateFormBean(BaseForm formBean, Object domainObject,
TransformationContext context) {
ReportsAbo rAbo = (ReportsAbo) domainObject;
ReportsAboForm reportsAboForm = (ReportsAboForm) formBean;
reportsAboForm.setEmailadresse(rAbo.getEmail());
}
In der ReportsAboAction wird zunächst die passende Transformationsklasse aus der TransformationRegistry geholt
protected Transformation getTransformation(HttpServletRequest request) {
return new TransformationWrapper(transformationRegistry.getTransformation(
ReportsAbo.class, ReportsAboForm.class));
}
Über dieses Objekt kann dann die populateFormBean-Methode aufgerufen werden.
Der Ablauf in der Actionklasse ist folgender Maßen. Standardmäßig wird die excute-Mehtode aufgerufen:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ReportsAboForm reportsAboForm = (ReportsAboForm) form;
String typeName = getParameter(request, PARAM_STATUS);
if (typeName != null) {
try {
Type type = Type.valueOf(typeName.toUpperCase());
switch (type) {
case NEW:
initForm(request, reportsAboForm);
...
In der Methode initForm wird Formbean zurückgesetzt und ein neues Domainobjekt erzeugt:
protected void initForm(HttpServletRequest request, BaseForm baseForm) {
ReportsAboForm form = (ReportsAboForm) baseForm;
form.reset();
ReportsAbo rAbo = new ReportsAbo();
form.setStatus("NEW");
form.setPropertyPathAccess(new EmptyPropertyPathAccess());
ActionContext.resetSessionAttributes(this, request);
populateWithDeletion(request, form, rAbo, null);
}
In der Methode populateWithDeletion wird die populateFormBean-Methode der Transformationsklasse aufgerufen:
protected void populateWithDeletion(HttpServletRequest request, BaseForm baseForm,
Object domainObject, StatePreserve statePreserve) {
Transformation tf = getTransformation(request);
tf.populateFormBean(baseForm, (IPersistentCapable) domainObject,
new TransformationContext(request, null));
}
In der zugehörigen JSP Seite wird die Formbean in einer Variable gesetzt:
<c:set var="item" value="${reportsAboForm}" />
Über
<c:out value="${item.emailadresse}"/>
Kann man auf den Wert zugreifen der in der Formbean gesetzt ist.