VERSIONES
- 20/08/2013 (Primera publicación)
- 23/01/2015: Formato de fecha
El plugin JSON permite a un Action devolver el valor de sus atributos (en realidad sus getters) serializados en JSON. Esto es especialmente útil si implementamos una intefaz web con un uso intensivo de AJAX y queremos renderizar los cambios en el navegador con JavaScript haciendo que el servidor devuelva sólo los datos que necesitemos en JSON lugar de generar todo el código HTML. Algunos widgets del plugin JQuery para Struts 2 se basan en esta funcionalidad.
Nota 1:Para «parsing» de JSON y Java consultar el tutorial sobre Gson.
Nota 2: para construir servicios REST con Action de Struts 2 utilizar este plugin.
Para poder usar este plugin, sólo hay que realizar dos sencillos pasos:
- Incluir el .jar con el plugin. En Maven usaríamos la siguiente dependencia:
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-json-plugin</artifactId> <version>${struts2.version}</version> </dependency>
- «Heredar» del paquete json-default
<package name="default" namespace="/" extends="struts-default,json-default">
Con estos pasos tan sencillos tenenemos disponibles el type json para nuestro results, todo muy simple y transparente. En el proyecto de ejemplo se va a usar este Action:
package com.danielme.tips.struts2.actions; import java.util.GregorianCalendar; import java.util.LinkedList; import java.util.List; import com.danielme.tips.struts2.model.Actor; import com.opensymphony.xwork2.ActionSupport; /** * * @author danielme.com * */ public class ResultJsonAction extends ActionSupport { private static final long serialVersionUID = 1L; private static List<Actor> actores; /** ACCIONES **/ public String execute() { if (actores == null) { Actor actor1 = new Actor("TH", "Tomk Hanks", new GregorianCalendar(1966, 6, 9)); Actor actor2 = new Actor("NW", "Naomi Watts", new GregorianCalendar(1968, 8, 28)); Actor actor3 = new Actor(null, "Natalie Porman", new GregorianCalendar(1981, 5, 9)); actores = new LinkedList<Actor>(); actores.add(actor1); actores.add(actor2); actores.add(actor3); } return SUCCESS; } public List<Actor> getActores() { return actores; } public String getTexto() { return "Hola mundo!!!"; } }
Su definición es la siguiente:
<package name="default" namespace="/" extends="struts-default,json-default"> <action name="inicio" class="com.danielme.tips.struts2.actions.ResultJsonAction"> <result type="json"/> </action> </package>
La llamada a este Action devuelve la lista de actores y el Hola mundo
El plugin proporciona varias posibilidades de configuración descritas en la documentación. Quizás las más útiles a priori sean las siguientes:
- Excluir atributos (getters) de la serialización:
<result type="json"> <param name="excludeProperties">texto</param> </result>
- Excluir nulos:
<result type="json"> <param name="excludeNullProperties">true</param> </result>
- Personalizar el formato de las fechas (Date y Calendar). Se hace con la anotación JSON
@JSON(format="dd-MM-YYYY") public Calendar getFechaNacimiento() { return fechaNacimiento; }
También se puede establecer un formato por defecto en el struts.xml a partir de la versión 2.3.20.
<constant name="struts.json.dateformat" value="dd-MM-YYYY"/>
- Cambiar el nombre con el que un atributo se mapea en el JSON. Volvemos a usar la misma anotación.
@JSON(name="nombre_completo") public String getNombre() { return nombre; }
Si aplicamos todos estos cambios el resultado debidamente formateado (y el que devuelve el proyecto de ejemplo) es el siguiente:
{ "actores" : [ { "cod" : "TH", "fechaNacimiento" : "09-07-1966", "nombre_completo" : "Tomk Hanks" }, { "cod" : "NW", "fechaNacimiento" : "28-09-1968", "nombre_completo" : "Naomi Watts" }, { "fechaNacimiento" : "09-06-1981", "nombre_completo" : "Natalie Porman" } ] }
El proyecto completo para Maven se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.
se puede usar sin maven?
Sí, tendrás que tener en el WEB-INF/libs los jar que necesites pero es muy recomendable utilizar Maven para no tener que gestionar las dependencias copiando manualmente ficheros.