Struts ist ein sehr flexibles und leistungsfähiges Open-Source-Framework für Thin-Client-Webanwendungen zur Standardisierung der Verarbeitung von Requests.
Clientseitig werden dabei HTML-Seiten (eventuell ergänzt um CSS und JavaScript) im Webbrowser eingesetzt.
Serverseitig findet Java Verwendung in Form von Servlets, JSP (Java Server Pages) und JavaBeans (eventuell auch EJB und weitere Java-EE-Komponenten).
Vorteile von Struts sind die Vereinfachung und Standardisierung von:
+ Requestverarbeitung
+ Validierung der Benutzereingaben
+ Fehlerbehandlung
+ Internationalisierung und Lokalisierung
+ Trennung der Präsentationsschicht von der Logikschicht
+ Erweiterbarkeit
Im folgenden ersten Teil wird ein einfaches Beispiel mit manueller Validierung vorgestellt (per 'validate()' in 'ActionForm').
Im "zweiten Teil" wird ein Beispiel mit dynamisch erzeugter Daten-JavaBean (DynaBean) und deklarativer Validierung (StrutsValidator) vorgestellt (per 'DynaValidatorForm' und 'validation.xml').
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <display-name>My Struts Application</display-name> <!-- Standard Action Servlet Configuration (with debugging) --> <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> <init-param> <param-name>debug</param-name> <param-value>2</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>2</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <!-- Standard Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- The Usual Welcome File List --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <logic:redirect forward="startForwardName" />
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html locale="true"> <head> <title><bean:message key="welcome.title" /></title> <html:base /> </head> <body bgcolor="white"> <logic:notPresent name="org.apache.struts.action.MESSAGE" scope="application"> <font color="red">ERROR: Application resources not loaded</font> </logic:notPresent> <h3><bean:message key="welcome.heading" /></h3> <p> <bean:message key="welcome.message" /></p> <html:form action="/htmlFormActionPath" focus="username"> <p> <bean:message key="welcome.Name" />: <html:text property="username" size="40" maxlength="40" /><br/> <font color=red><html:errors property="username" /></font></p> <p> <bean:message key="welcome.Password" />: <html:text property="password" size="40" maxlength="40" /><br/> <font color=red><html:errors property="password" /></font></p> <p> <html:submit property="action" value="Weiter" /> <html:submit property="action" value="Abbrechen" /></p> </html:form> </body> </html:html>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:html> <head> <title>Ergebnisanzeige</title> </head> <body> <h1>Eingegebene Daten</h1> <p> Name: <b><bean:write property="username" name="MeinDatenFormBeanName" /></b></p> <p> Passwort: <b><bean:write property="password" name="MeinDatenFormBeanName" /></b></p> </body> </html:html>
package meinpackage; import javax.servlet.http.*; import org.apache.struts.action.*; public final class MeineDatenFormBean extends ActionForm { private String username = null; private String password = null; private String action = null; public String getUsername() { return this.username; } public String getPassword() { return this.password; } public String getAction() { return this.action; } public void setUsername( String username ) { this.username = username; } public void setPassword( String password ) { this.password = password; } public void setAction( String action ) { this.action = action; } public void reset( ActionMapping mp, HttpServletRequest rq ) { username = null; password = null; action = null; } public ActionErrors validate( ActionMapping mp, HttpServletRequest rq ) { ActionErrors errors = null; if( !"Weiter".equals( action ) ) { username = null; password = null; } else { if( username == null || username.length() < 1 ) { if( errors == null ) errors = new ActionErrors(); errors.add( "username", new ActionError( "error.username.required" ) ); } if( password == null || password.length() < 1 ) { if( errors == null ) errors = new ActionErrors(); errors.add( "password", new ActionError( "error.password.required" ) ); } } return errors; } }
package meinpackage; import javax.servlet.http.*; import org.apache.struts.action.*; public final class MeineAuswerteAction extends Action { public ActionForward execute( ActionMapping mp, ActionForm fm, HttpServletRequest rq, HttpServletResponse rp ) { MeineDatenFormBean dfb = (MeineDatenFormBean)fm; String sAction = dfb.getAction(); return mp.findForward( sAction ); } }
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="MeinDatenFormBeanName" type="meinpackage.MeineDatenFormBean" /> </form-beans> <global-forwards> <forward name="startForwardName" path="/StartActionPath.do" /> </global-forwards> <action-mappings> <action path="/StartActionPath" forward="/pages/EingabeFormular.jsp" /> <action path="/htmlFormActionPath" type="meinpackage.MeineAuswerteAction" name="MeinDatenFormBeanName" scope="request" input="/pages/EingabeFormular.jsp"> <forward name="Weiter" path="/ErgebnisanzeigeActionPath.do" /> <forward name="Abbrechen" path="/StartActionPath.do" /> </action> <action path="/ErgebnisanzeigeActionPath" forward="/pages/ErgebnisAnzeige.jsp" /> </action-mappings> <message-resources parameter="resources.MessageResources" /> </struts-config>
# -- standard errors -- errors.header=<UL> errors.prefix=<LI> errors.suffix=</LI> errors.footer=</UL> # -- validator -- errors.invalid={0} is invalid. errors.maxlength={0} can not be greater than {1} characters. errors.minlength={0} can not be less than {1} characters. errors.range={0} is not in the range {1} through {2}. errors.required={0} is required. errors.byte={0} must be an byte. errors.date={0} is not a date. errors.double={0} must be an double. errors.float={0} must be an float. errors.integer={0} must be an integer. errors.long={0} must be an long. errors.short={0} must be an short. errors.creditcard={0} is not a valid credit card number. errors.email={0} is an invalid e-mail address. # -- other -- errors.cancel=Operation cancelled. errors.detail={0} errors.general=The process did not complete. Details should follow. errors.token=Request could not be completed. Operation is not in sequence. # -- welcome -- welcome.title=My Struts Application welcome.heading=Welcome! welcome.message=First small Struts Application. Reads some information and displays them. welcome.Name=Name welcome.Password=Password error.username.required=Error: Username required! error.password.required=Error: Password required!
# -- welcome -- welcome.title=Meine Struts Applikation welcome.heading=Willkommen! welcome.message=Erste kleine Struts-Anwendung. Liest Informationen ein und gibt sie wieder. welcome.Name=Name welcome.Password=Passwort error.username.required=Fehler: Benutzername wird benötigt! error.password.required=Fehler: Passwort wird benötigt!
<project name="blank" basedir="../" default="all"> <!-- Local system paths --> <property name="servlet.jar" value="/Tools/Tomcat/common/lib/servlet-api.jar" /> <property name="jdbc20ext.jar" value="/Tools/Tomcat/common/lib/jdbc2_0-stdext.jar" /> <!-- NOTE: If "dist" target is used, a local "projects/lib" directory will be utilized or created --> <property name="distpath.project" value="/projects/lib" /> <!-- Project settings --> <property name="project.title" value="Meine Struts Applikation " /> <property name="project.distname" value="mystrutsapp" /> <!-- Path settings --> <property name="doc.path" value="./doc/api" /> <property name="doc.src" value="./src" /> <!-- classpath --> <path id="compile.classpath"> <pathelement path="${servlet.jar}" /> <pathelement path="lib/commons-beanutils.jar" /> <pathelement path="lib/commons-digester.jar" /> <pathelement path="lib/struts.jar" /> <pathelement path="classes" /> <pathelement path="${classpath}" /> </path> <!-- Check timestamp on files --> <target name="prepare"> <tstamp/> </target> <!-- Copy any resource or configuration files --> <target name="resources"> <copy todir="classes" includeEmptyDirs="no"> <fileset dir="src"> <patternset> <include name="**/*.conf" /> <include name="**/*.properties" /> <include name="**/*.xml" /> <exclude name="build.xml" /> </patternset> </fileset> </copy> </target> <!-- Normal build of application --> <target name="compile" depends="prepare,resources"> <javac srcdir="src" destdir="classes"> <classpath refid="compile.classpath" /> </javac> </target> <!-- Remove classes directory for clean build --> <target name="clean" description="Prepare for clean build"> <delete dir="classes" /> <mkdir dir="classes" /> </target> <!-- Build Javadoc documentation --> <target name="javadoc" description="Generate JavaDoc API docs"> <delete dir="./doc/api" /> <mkdir dir="./doc/api" /> <javadoc sourcepath="./src" destdir="./doc/api" classpath="${servlet.jar}:${jdbc20ext.jar}" packagenames="*" author="true" private="true" version="true" windowtitle="${project.title} API Documentation" doctitle="<h1>${project.title} Documentation (Version ${project.version})</h1>" bottom="Copyright © 2005"> <classpath refid="compile.classpath" /> </javadoc> </target> <!-- Build entire project --> <target name="project" depends="clean,prepare,compile,javadoc" /> <!-- Create binary distribution --> <target name="dist" description="Create binary distribution"> <mkdir dir="${distpath.project}" /> <jar jarfile="${distpath.project}/${project.distname}.jar" basedir="./classes" /> <copy file="${distpath.project}/${project.distname}.jar" todir="${distpath.project}" /> <war basedir="../" warfile="${distpath.project}/${project.distname}.war" webxml="web.xml"> <exclude name="${distpath.project}/${project.distname}.war" /> </war> </target> <!-- Build project and create distribution--> <target name="all" depends="project,dist" /> </project>
... siehe zweiter Teil.