21/10/2013
Convention Plugin permite configurar una aplicación Struts 2 sin necesidad de definirla en struts.xml simplemente siguiendo una seríe de “convenciones” o criterios en la paquetería de nuestros actions y en la ubicación de los ficheros de la vista (html, jsp, etc). Esta configuración automática puede ser modificada mediante anotaciones en las clases Action y es precisamente esta funcionalidad la que expondrá el presente tip.
El ejemplo que vamos a ver consistirá en una pequeña aplicación que usa struts.xml y que se migrará a anotaciones. El struts.xml es el siguiente (he añadido la configuración de un interceptor con fines educativos)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.custom.i18n.resources" value="global" /> <package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor-stack name="customStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="customStack" /> <action name="mainAction" class="com.danielme.tips.struts2.tip9.actions.MainAction" method="main"> <result name="success">/jsp/form.jsp</result> </action> <action name="oneAction" class="com.danielme.tips.struts2.tip9.actions.MainAction" method="resultOne"> <result name="success">/jsp/resultOne.jsp</result> </action> <action name="twoAction" class="com.danielme.tips.struts2.tip9.actions.MainAction" method="resultTwo"> <result name="success">/jsp/resultTwo.jsp</result> </action> </package> </struts>
Los .jsp serán los siguientes
form.jsp
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <%@include file="/jsp/head.jsp" %> </head> <body> <s:form action="oneAction"> <s:submit value="%{getText('resultOne')}"/> </s:form> <s:form action="twoAction"> <s:submit value="%{getText('resultTwo')}"/> </s:form> <%@include file="/jsp/footer.jsp" %> </body> </html>
resultOne.jsp
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <%@include file="/jsp/head.jsp" %> </head> <body> <h3><s:text name="resultOne"/></h3> <s:form action="mainAction"> <s:submit value="%{getText('back')}"/> </s:form> <%@include file="/jsp/footer.jsp" %> </body> </html>
resultTwo.jsp
<%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <%@include file="/jsp/head.jsp" %> </head> <body> <h3><s:text name="resultTwo"/></h3> <s:form action="mainAction"> <s:submit value="%{getText('back')}"/> </s:form> <%@include file="/jsp/footer.jsp" %> </body> </html>
El Action ya lo veremos más adelante anotado. Para utilizar Convention Plugin lo único que hay que hacer es incluirlo en nuestra aplicación, en mi caso en el pom.xml del proyecto:
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-convention-plugin</artifactId> <version>${struts2.version}</version> </dependency>
Y ahora, el Action debidamente anotado.
package com.danielme.tips.struts2.tip9.actions; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.InterceptorRefs; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.Result; import com.opensymphony.xwork2.ActionSupport; /** * * @author danielme.com * */ @Namespace("/") //interceptors can also be defined at method level @InterceptorRefs({ @InterceptorRef(value = "defaultStack"), @InterceptorRef(value = "store", params = {"operationMode", "AUTOMATIC"}) }) public class MainAction extends ActionSupport { private static final long serialVersionUID = 4032858540744383204L; @Action( value="mainAction", results= {@Result(name=SUCCESS, type="dispatcher", location="/jsp/form.jsp") } ) public String main() { return SUCCESS; } @Action( value="oneAction", results= {@Result(name=SUCCESS, type="dispatcher", location="/jsp/resultOne.jsp") } ) public String resultOne() { return SUCCESS; } @Action( value="twoAction", results= {@Result(name=SUCCESS, type="dispatcher", location="/jsp/resultTwo.jsp") } ) public String resultTwo() { return SUCCESS; } }
Si ejecutamos la aplicación, podremos comprobar que el funcionamiento es el mismo tanto si usamos struts.xml o la configuración con anotaciones. La siguiente captura muestra el proyecto de ejemplo.
El proyecto completo para Maven se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.