1. Diferencias con Struts 1
  2. Descarga | Instalación con Maven
  3. Redireccionamientos
    1. Redireccionamiento directo
    2. Redireccionamiento al método execute del action
    3. Redireccionamiento a un método concreto del action
    4. Redireccionamiento a un método con paso de parámetros
    5. La salida de un action es la entrada de otro
  4. Errores típicos
  5. Maquetación y Struts 2
  6. Ejercicios
  7. Notas Struts2
  8. Ejercicio librería
  9. Internacionalización
  10. Validación
  11. Ejercicio hospital
  12. Ejercicio futbol
  13. Tiles
  14. Upload File
  15. Struts2 y Ajax
  16. Ejercicio paginación

Diferencias con Struts1

Struts2 tiene configuración por defecto.

Ahora el struts-config.xml se llama struts.xml y está en otro sitio (paquete src).

Redireccionamientos

Redireccionamiento directo

index.jsp<a href="enlace.action">Enlace</a>
WebContent/WEB-INF/web.xml<?xml version="1.0" encoding="utf-8" ?>
<web-app
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
	http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
</web-app>
src/struts.xml<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="com.pablomonteserin.action" extends="struts-default">
		<action name="enlace">
			<result>/pagina2.jsp</result>
		</action>
	</package>
</struts>
página2.jspLlegamos a ĺa página 2
Descarga (utilizaremos este ejercicio como base para los siguientes)

Redireccionamiento al método execute del action

index.jsp<a href="accion.action">Enlace a acción</a>
struts.xml<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<package name="com.pablomonteserin.action" extends="struts-default">
		<action name="accion" class="com.pablomonteserin.action.SaludarAction">
			<result>/pagina2.jsp</result>
		</action>
	</package>
</struts>
SaludarAction.java
public class SaludarAction extends ActionSupport {
	private String resultado;

	public String execute(){
		resultado = "Hola Pablo";
		return SUCCESS;
	}
	//getters y setters el atributo resultado
}
pagina2.jsp<%@ taglib prefix="s" uri="/struts-tags"%>
<h2><s:property value="resultado" /></h2>

Redireccionamiento a un método concreto del action

index.jsp<a href="accion2.action">Enlace a acción</a>
struts.xml<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<package name="com.pablomonteserin.action" extends="struts-default">
		<action name="accion2" class="com.pablomonteserin.action.SaludarAction" method="saludar">
			<result>/pagina2.jsp</result>
		</action>
	</package>
</struts>
SaludarAction.javapublic class SaludarAction extends ActionSupport {
	private String resultado;

	public String saludar(){
		resultado = "Hola Juan";
		return SUCCESS;
	}
	//getters y setters para el atributo resultado
}
pagina2.jsp<%@ taglib prefix="s" uri="/struts-tags"%>
<h2><s:property value="resultado" /></h2>

Redireccionamiento a un método con paso de parámetros

Debemos definir estos parámetros como atributos globales dentro del action y hacer sus correspondientes getters y setters

La salida de un action es la entrada de otro

struts.xml<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<package name="com.pablomonteserin.action" extends="struts-default">
		<action name="accionRedireccion" class="com.pablomonteserin.action.SaludarAction" method="saludar">
			<result type="redirectAction">accion3</result>
		</action>
	</package>
</struts>

Notas:
Si usamos type="chain", redireccionaremos a otro bean, pero cuando finalmente vayamos a un jsp, le llegará la información del penúltimo action ejecutado.

Errores típicos

Error 404
Es posible que en el struts.xml se haga referencia a una clase Java que realmente no existe.

Maquetación y Struts 2

Por defecto Struts2 añade etiquetas de tablas a las etiquetas de los formularios. Esto puede dar problemas a la hora de maquetar un formulario. Para evitarlos usaremos el atributo theme="simple":

<s:textfield  name="mes" size="2" maxlength="4" theme="simple"/>

También puedo utilizar este atributo en el formulario, con lo cual todos los inputs del mismo se maquetarán sin estructura de tabla.

Formularios

nombre.jsp	<%@ taglib prefix="s" uri="/struts-tags"%>
<s:form method="post" action="Saludar">				
	<s:textfield label="Introduce tu nombre" name="titulo.nombre"/>
	<s:submit/>
</s:form>
Imprimir una combo concatenando el texto mostrado:<s:select name="paciente.id" list="pacientes" headerKey="0" headerValue="Select One" listKey="id" listValue="nombre+'  '+apellidos" />
Puedes tener un botón que efectúe un action específico sin necesidad de programarlo con javascript:<s:submit action="baja" />
y luego, en el struts.xml:<constant name="struts.mapper.action.prefix.enabled" value="true"/>
<package nam...

Ejercicios

Ejercicio

Hacer un action llamado "SumadorAction" con 3 propiedades: n1, n2 y suma, sus correspondientes métodos getters y setters y un método execute que sumará estos dos números y devolverá la suma.

Ingresaremos los datos mediante un formulario y tras hacer submit iremos a una página dónde visualizaremos el resultado de la operación.

Ejercicio

Hacer una calculadora. Gestionar y realizar la operación desde dentro del método execute

Combo con valores harcodeados en struts2:
<s:select list="#{'value1':'txtMostrado1', 'value2':'txtMostrado2'}" name="operacion"/>

Calculadora Struts 2

Notas Struts2

En struts2 utilizaremos una única clase java que será llamada por todos los action de un mismo mantenimiento (alta, baja, modificación y consulta).

Mapear propiedades:

Puedo mapear directamente las propiedades de un bean si desde la vista utilizo el nombre del bean junto con la propiedad que quiero mapear:

<s:textfield name="paciente.nombre" value="%{paciente.nombre}" />

Recorrer una colección:<s:iterator value="libros">
	<s:property value="titulo"/> - 
	<s:property value="precio"/>
</s:iterator>

Ejercicio librería

Foto ejercicio librería struts 2

Recomendación:
Usar decimal para el precio en la base de datos, en lugar de Float o Double. Esto nos ahorrará problemas al trabajar con los decimales.

Ejercicio - usar Treemap

Realizar el ejercicio anterior utilizando un TreeMap de libros que será almacenado en la sesión. Al iniciar la aplicación el SessionListener almacenará en la sesión un treemap con los libros que hay en la base de datos. A partir de ese momento, las operaciones se realizarán directamente sobre la sesión, sin utilizar la base de datos.

Uso de la sesión desde un action de Struts2:Map session = ActionContext.getContext().getSession();
TreeMap libros = (TreeMap) session.get("libros");
Uso de la sesión desde un listener:HttpSession session = arg0.getSession();
session.setAttribute("libros", new TreeMap());
Recorrer un TreeMap con iterator: <s:iterator value="libros" >
	<s:property value="value.titulo"/></a></td>
</s:iterator>
Recorrer una collection almacenada en la session:<s:iterator value="#session.personas">
	<s:property value="nombre"/><br/>
	<s:property value="edad"/><br/>
	<hr/>
</s:iterator>
Descargar librería Struts 2

Internacionalización

Hola Mundo con internacionalización

struts.xml<constant name="struts.custom.i18n.resources" value="global" />
global.properties (en la raíz de la carpeta src)pagina_inicio.holaMundo = Hola mundo\!\!

Si este fichero tiene acentos, caracteres asiáticos, etc, podemos hacer que se vean correctamente utilizando la herramienta que viene entre los binarios (carpeta bin) del jdk:
native2ascii -encoding utf8 C:\source.txt C:\output.txt

HelloWorld.jsp<%@ taglib prefix="s" uri="/struts-tags"%>
<s:text name="pagina_inicio.holaMundo" />
Para poner un textfield con label:
<s:textfield key="login.username" name="username" />

Internacionalización – varios idiomas

-src
	- global.properties
	- global_pt.properties
	- global_es.properties
HelloWorld.jsp<a href="location.action?request_locale=es">En Español</a>
<a href="location.action?request_locale=pt">En Portugués</a></p>
La clase vinculada a location.action no hace nada en particular:
<action name="location">
	<result>HelloWorld.jsp</result>
</action>
Basta con el el parámetro enviado sea request_locale para que se produzca correctamente el cambio del idioma.

Si queremos cargar el español, y el español es el idioma por defecto, dejaremos en blanco el fichero global_es.properties, de tal forma que al no encontrar nada, el sistema se irá a leer el fichero de configuración por defecto, que estará en español.

Internacionalización imprimiendo valores dentro de un atributo. Hay dos formas

HelloWorld.jsp<%@ taglib prefix="s" uri="/struts-tags"%>
<h2>
<s:property value="%{getText('resource.msg')}" />
<s:property value="mensaje" />
</h2>

Cuando queramos usar internacionalización en el atributo de una etiqueta, utilizaremos esta forma de cargar los textos.
global.propertiesresource.msg = Seleccione una opción, por favor

HelloWorld.java
public class HelloWorld extends ActionSupport {
	private String mensaje;

	public String recuperaMensaje(){
		setMensaje(getText("resource.msg"));
		/*nota:
		Es posible recuperar el idioma actual usando:
		Locale loc = getLocale(); */
		return SUCCESS;
	}
	public String getMensaje() {
		return mensaje;
	}

	public void setMensaje(String mensaje) {
		this.mensaje = mensaje;
	}
}

Nota!

Obtener el nombre del action que se está ejecutando:

String action = com.opensymphony.xwork2.ActionContext.getContext().getName();
System.out.println(action);	

Validación

index.jsp<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:head/>
<s:form action="Register" >
	<s:textfield label="User Name" key="user.username"/>
	<s:password label="Password" key="user.password" />
	<s:textfield label="Email" key="user.email" />
	<s:submit/>
</s:form>
PacienteAction.java (el action debe tener los getters y
setters de las propiedades que quiero validar o no se producirá la validación).
PacienteAction-validation.xml (mismo paquete que PacienteAction.java)<!DOCTYPE validators PUBLIC
"-//Apache Struts//XWork Validator 1.0.2//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd">
<validators>
<field name="user.username">
	<field-validator type="requiredstring"><message key="validateRequired"/></field-validator>
</field>
<field name="user.password">
	<field-validator type="requiredstring"><message key="validateRequired"/></field-validator>
        <field-validator type="stringlength">
		<param name="minLength">6</param>
		<param name="trim">true</param>
		<message key="validatePassword"/>
	</field-validator>
</field>
<field name="user.email">
	<field-validator type="requiredstring"><message key="validateRequired"/></field-validator>
        <field-validator type="email"><message key="validateMail"/></field-validator>
</field>
</validators>
package.propertiesvalidateRequired = ${getText(fieldName)} is required.
validateMail = ${getText(fieldName)} is not in correct format.
validatePassword = ${getText(fieldName)} should be more than 6 character.
struts.xml<action name="Register" class="com.PacienteAction">
	<result>/index.jsp</result>
	<result name="input">index.jsp</result>
</action>

PacienteAction.java , PacienteAction-validation.xml y package.properties deben estar en el mismo paquete

Nota:
Lo más apropiado es definir los mensajes de los errores de validación en los ficheros package.properties y las etiquetas de los elementos en los ficheros global. Para mostrar los errores de validación no es necesario registrar los ficheros package.properties en el struts.xml. Sin embargo, si queremos elementos del tipo hagan uso de los valores definidos en estos ficheros, si que deberemos definirlos en el struts.xml

Validar un número

index.jsp<s:head/>
<s:form action="Register" >
	<s:textfield key="numero" /> 
	<s:submit/>
</s:form>
ValidationAction-validation.xml<!DOCTYPE validators PUBLIC
        "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
        "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
	<field name="numero">
		<field-validator type="regex">
		<param name="expression"><![CDATA[^\d*$]]></param>
		<message> Debe ser un entero</message>
		</field-validator>
	</field>
</validators>
package.properties
invalid.fieldvalue.numero = debes introducir un número

Con la línea anterior lo que hacemos es personalizar el mensaje de error Invalid field value for field "numero" que obtendríamos al convertir un texto en un número.

Validación con theme="simple"

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
    <s:head/>
    <s:fielderror />
<s:form action="Register2" theme="simple" >
    <s:textfield key="user.username"/>
	<s:fielderror fieldName="user.username" /><br/>
    <s:password key="user.password" />
	<s:fielderror fieldName="user.password" /><br/>
    <s:textfield key="user.email"/>
	<s:fielderror fieldName="user.email" /><br/>
    <s:submit/>
</s:form>

Nota:
para quitar las etiquetas ul y li que general el fielderror, habrá que modificar struts2-core-2.0.11.1.jar/template/simple/fielderror.ftl y quitarlas de ahí.

Otras validaciones

<validators>
  <field name="bar">
      <field-validator type="required">
          <message>You must enter a value for bar.</message>
      </field-validator>
      <field-validator type="int">
          <param name="min">6</param>
          <param name="max">10</param>
          <message>bar must be between ${min} and ${max}, current value is ${bar}.</message>
      </field-validator>
  </field>
  <field name="bar2">
      <field-validator type="regex">
          <param name="expression">[0-9],[0-9]</param>
          <message>The value of bar2 must be in the format "x, y", where x and y are between 0 and 9</message>
     </field-validator>
  </field>
  <field name="date">
      <field-validator type="date">
          <param name="min">12/22/2002</param>
          <param name="max">12/25/2002</param>
          <message>The date must be between 12-22-2002 and 12-25-2002.</message>
      </field-validator>
  </field>
  <validator type="expression">
      <param name="expression">foo lt bar </param>
      <message>Foo must be greater than Bar. Foo = ${foo}, Bar = ${bar}.</message>
  </validator>
</validators>

Notas:

  • Documentación de validación
  • Cuando definimos una validación, esta se efectuará para todos los métodos de un action. Si no queremos que la validación se aplique sobre algún método en concreto, podemos usar la directiva:
    @SkipValidation
    precediendo al método.

Ejercicio

Rehacer el ejercicio del hospital utilizando Struts 2.

<s:select headerValue="Elija una opción" headerKey="-1" list="pacientes" multiple="false" listValue="%{nombre}" listKey="%{id}" name="paciente.id">
</s:select>

Notas;

  • Para que se vea el headerValue debe haberse definido un headerKey.
  • Para poner cuadros de texto en horizontal:
    <tr><td>Fecha de alta: </td>
    <td><s:textfield  size="2" maxlength="2" name="dia" theme="simple" />-
    	<s:textfield  name="mes" size="2" maxlength="4" theme="simple"/>-
    	<s:textfield size="4" maxlength="4" name="anio" theme="simple"/>
    </td></tr>		
  • Para mostrar una fecha podemos usar la etiqueta:
    <s:date name="fecha" format="dd/MM/yyyy" />

Redefinir la apariencia de una etiqueta (checkboxlist)

  1. Creo el paquete template.vertical_checkbox
  2. Dentro, creo el fichero checkboxlist.ftl
  3. Pego el siguiente código:
    <#assign itemCount = 0/>
    <#if parameters.list??>
    <@s.iterator value="parameters.list">
    <#assign itemCount = itemCount + 1/>
    <#if parameters.listKey??>
    <#assign itemKey = stack.findValue(parameters.listKey)/>
    <#else>
    <#assign itemKey = stack.findValue('top')/>
    </#if>
    <#if parameters.listValue??>
    <#assign itemValue = stack.findString(parameters.listValue)?default("")/>
    <#else>
    <#assign itemValue = stack.findString('top')/>
    </#if>
    <#assign itemKeyStr=itemKey.toString() />
    <input type="checkbox" name="${parameters.name?html}" value="${itemKeyStr?html}" id="${parameters.name?html}-${itemCount}" class="${parameters.cssClass?html}" <#rt/>
    <#if tag.contains(parameters.nameValue, itemKey)>
    checked="checked"<#rt/>
    </#if>
    <#if parameters.disabled?default(false)>
    disabled="disabled"<#rt/>
    </#if>
    <#if parameters.title??>
    title="${parameters.title?html}"<#rt/>
    </#if>
    <#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
    <#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
    />
    <label for="${parameters.name?html}-${itemCount}" class="checkboxLabel">${itemValue?html}</label>
    <br/>
    </@s.iterator>
    <#else>
    </#if>
  4. Debo utilizar el atributo theme al llamar a la etiqueta:
    <s:checkboxlist list="%{equipos}" name="codigosEquipo" listKey="equipoCod" listValue="nombre" theme="vertical_checkbox" />

Hacer una comparación

<s:set var="varMsg" value="%{'msg'}"/>
<s:property value="varMsg"/>
<s:if test="%{varMsg=='msg'}">Comparacion con éxito</s:if>

Problemas al hacer una comparación contra una única letra. (Hay que escapar las comillas de la letra para que en vez de un char lo trate como un String):

<s:if test="%{usuario.tipoUsuario==\"A\"}" > 
Éxito
</s:if>

Ejercicio futbol

Descargar fotografías. applicación futbol

La lista de checks marcadas será tratada como lista, en vez de como array. Para consultar los jugadores en función de dicha lista (que he llamado codigosEquipo), utilizaremos la siguiente consulta de Hibernate:

hqlQuery = session.createQuery("from Jugador j where j.equipo.equipoCod in (:listaDeParametros)");
hqlQuery.setParameterList("listaDeParametros", codigosEquipo);
private List<Integer> codigosEquipo; en el action directamente me castea la lista de Strings en una lista de Integers.

Para recuperar las checks de equipos sin tener que llamar expresamente a un method desde el struts.xml puedo sobreescribir el método getEquipos de EquiposAction:

public List getEquipos() {
	equipos = equipoBO.getEquipos();
	return equipos;
}

Ejercicio

En el ejercicio anterior, al mostrar la lista de jugadores, mostrar también el equipo al que pertenecen.

Jugador.hbm.xml
<many-to-one lazy="false" name="equipo" class="com.pablomonteserin.model.data.Equipo" fetch="select">
	<column name="equipo_cod" />
</many-to-one>
equipos.jsp
<s:property value="equipo.nombre" />

tiles

index.jsp
<meta http-equiv="Refresh" content="0;url=homePage.action">
web.xml
<listener>
	<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
struts.xml<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<package name="default" extends="struts-default">
		<result-types>
			<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
		</result-types>
		<action name="*Page">
			<result  type="tiles">{1}</result>
		</action>
	</package>
</struts>
tiles.xml (situado en la raíz de la carpeta WEB-INF)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
        <definition name="baseLayout" template="/layouts/baseLayout.jsp">
                <put-attribute name="title" value="Template" />
                <put-attribute name="header" value="/templates/header.jsp" />
                <put-attribute name="menu" value="/templates/menu.jsp" />
                <put-attribute name="body" value="/templates/body.jsp" />
        </definition>
        <definition name="home" extends="baseLayout">
                <put-attribute name="title" value="Home Page" />
                <put-attribute name="body" value="/pages/home.jsp" />
        </definition>
        <definition name="contactUs" extends="baseLayout">
                <put-attribute name="title" value="Contact Us Page" />
                <put-attribute name="body" value="/pages/aboutUs.jsp" />
        </definition>
</tiles-definitions>
baseLayout.jsp
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title><tiles:insertAttribute name="title" ignore="true" /></title>
</head>
<body>
	<div style="width:100%; height:70px; background:salmon; float:left">
	<tiles:insertAttribute name="header" />
	</div>
	<div style="width:200px; height:500px; background:pink; float:left">
		<tiles:insertAttribute name="menu" />
	</div>
	<div style="width:800px; height:500px; background:green; float:left">
		<tiles:insertAttribute name="body" />
	</div>
</body>
</html>
Descargar librerías de Struts 2.3.8 con tiles>

Problemas de codificación usando tiles

Puede ser útil añadir el siguiente código al web.xml, en el caso de que tengamos problemas con los acentos, para corregir problemas u obtener información de ellos:

<web-app>
    ...
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <page-encoding>UTF-8</page-encoding>
            <trim-directive-whitespaces>true</trim-directive-whitespaces>
        </jsp-property-group>
    </jsp-config>    
</web-app>

Upload file (subir fichero)

index.jsp
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
	<head><title>Struts2 File Upload Example</title></head>
	<body>
		<s:actionerror/>
		<s:fielderror/>
		<s:form action="UploadMyFile" enctype="multipart/form-data" method="POST">
			<s:file name="uploadFile" label="Please select a file to upload"></s:file>
			<s:submit></s:submit>
		</s:form>
	</body>
</html>
struts.xml<action name="UploadMyFile" class="com.pablomonteserin.action.FileUploadAction">
	<interceptor-ref name="defaultStack">
		<param name="fileUpload.allowedTypes">text/plain,image/png,image/gif,image/jpeg</param>
		<param name="fileUpload.maximumSize">200000</param>
	</interceptor-ref>
	<result name="success">/uploadedFile.jsp</result>
</action>
FileUploadAction.java//Habría que poner los getters y setters de fileSize(long), uploadFileFileName(String) y uploadFile(File)
public String execute() throws Exception {
	String filePath = "/home/monty/Desktop/"+uploadFileFileName;
	File newFile = new File(filePath);
	FileUtils.copyFile(uploadFile, newFile);
	return SUCCESS;
}

combobox tag

<s:form>
	Para que funcione correctamente, el combobox debe estar dentro de un formulario, ya que dicho formulario será referenciado en el código javascript que genera la etiqueta
	<s:combobox label="My Favourite Color" name="myFavouriteColor" list="#{'red':'red','green':'green','blue':'blue'}" headerKey="-1" headerValue="--- Please Select ---" emptyOption="true" value="green" />
	<s:combobox label="Personas" name="persona" list="personas" headerKey="-1" headerValue="--- Please Select ---" listValue="nombre" listKey="id" emptyOption="true" value="Juan" />
</s:form>

Struts 2 y Ajax

Consultar las diapositivas de Ajax y Query hasta la diapositiva: ''Enviar un array múltiple'' inclusive.

Tener en cuenta que a partir de la versión 1.4 de Jquery cambió la forma de enviar objetos, y dejó de ser compatible con algunos frameworks, como Struts 2. Para utilizar la metodología antigua de envio de la información:

<script type="text/javascript">
jQuery.ajaxSettings.traditional = true; 
….

Una combo carga en función de otra

Cargar una combo con los equipos de futbol y tras seleccionar un equipo, utilizando ajax, cargar otra comobo con los jugadores del equipo seleccionado.

Utilizaremos el siguiente código Jquery:

$(document).ready(function(){
	$("#combo1").change(function(event){
		//almacenamos en id el value de la option seleccionada
		var id = $("#combo1").find(':selected').val();
		$.get('cargaComboJugadores.action', { 'equipoCod': id}, showResult, "text");
	});
});

Enviar y gestionar objetos serializados

Generaremos un objeto JSON a partir de los resultados de una consulta en la base de datos. Leeremos dichos resultados con Javascript.

prueba-ajax.html<script>
$.ajax({
	url: "https://app-futbol.herokuapp.com/verEquiposAjax.action",
	dataType:'JSON',
	type: "GET",
	crossDomain: true,
	contentType: "application/json",
	success: function(response){
		console.log(response)
		for(var i =0; i<response.length; i++){
			console.log(response[i].nombre)
		}
	}
})
</script>
struts.xml<action name="verEquiposAjax" class="com.pablomonteserin.action.EquipoAction" method="verEquiposAjax">
	<result>/equipos-ajax.jsp</result>
</action>
En el Action:public String verEquiposAjax() {
	EquiposBO equiposBO = new EquiposBO();
	equipos = equiposBO.getEquipos();
	Gson gson = new GsonBuilder().create();
	codigo = gson.toJson(equipos);
	return SUCCESS;
}
equipos-ajax.jsp<s:property  escapeXml="false" escapeHtml="false" escapeJavaScript="false" value="personaSerializada" />
Descargar ejemplo

Ejercicio paginación

Hacer una paginación sobre el listado completo de jugadores. En dicha paginación simplemente se mostrarán los nombres de los jugadores.

Para paginar dividimos la información en bloques de registros. Si cada página (o bloque) tiene 10 registros y quiero ir a la página 3, haré una consulta que vaya al registro 30 y a partir de ahí me devuelva los siguientes 10 registros.

Para que una consulta comience a partir de cierto registro, usaré el siguiente método:

hqlQuery.setFirstResult(registro);

Para que una consulta no me devuelva más de 10 resultados, usaré el siguiente método:

hqlQuery.setMaxResults(10);

Para imprimir los enlaces a cada una de las páginas, utilizaré el siguiente código:

<s:iterator begin="1" end="numRegistros" step="10" status="i">
	<a class="enlace" href="inicioPaginacion.action?reg=<s:property value="#i.index*10"/>"><s:property value="#i.count"/>
	</a>
</s:iterator>
icono de mandar un mail¡Contacta conmigo!
contacta conmigoPablo Monteserín

¡Hola! ¿En qué puedo ayudarte?