
Antes unos pequeños apuntes de porque nos puede interesar devolver json o xml. Unos de los motivos es que a medida que las aplicaciones web están ganando en complejidad estas están tendiendo a delegar en el cliente la parte de visualización en vez de ser el servidor el que devuelva html formateado directamente. Además de evitar cierta carga de proceso en el servidor y delegarla en los clientes ofreciendo una interfaz REST de la apliccación permitimos que terceros desarrollen sus propias aplicaciones y se integren consumiendo los servicios que ofrecemos.
Una vez explicadas algunas ventajas, veamos el ejemplo de como devolver json o xml en el servicio REST, en el siguiente código el servicio HelloWorldResource devolverá los datos de un objeto a través de los métodos getMensajeJSON y getMensajeXML. Los métodos del servicio puede anotarse con @Produces indicando el formato de los datos que se devuelve, en la clase MediaType hay constantes para muchos formatos. Si el formato en el que devolvemos los datos no está definido en la clase MediaType podemos definir uno específico con @Produces("text/html"):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.resteasy; | |
import javax.ws.rs.GET; | |
import javax.ws.rs.Path; | |
import javax.ws.rs.PathParam; | |
import javax.ws.rs.Produces; | |
import javax.ws.rs.core.MediaType; | |
@Path("/helloworld") | |
public interface HelloWorldResource { | |
@GET | |
@Path("/saluda") | |
public String getSaluda(); | |
@GET | |
@Path("/saluda/{nombre}") | |
public String getSaludaA(@PathParam("nombre") String nombre); | |
@GET | |
@Path("/mensaje/{nombre}") | |
@Produces(MediaType.APPLICATION_JSON) | |
public Mensaje getMensajeJSON(@PathParam("nombre") String nombre); | |
@GET | |
@Path("/mensaje/{nombre}") | |
@Produces(MediaType.APPLICATION_XML) | |
public Mensaje getMensajeXML(@PathParam("nombre") String nombre); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.resteasy; | |
import java.text.MessageFormat; | |
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
import javax.ws.rs.Path; | |
import javax.ws.rs.PathParam; | |
public class HelloWorldResourceImpl implements HelloWorldResource { | |
@Override | |
public String getSaluda() { | |
return "¡Hola mundo!"; | |
} | |
@Override | |
public String getSaludaA(String nombre) { | |
return MessageFormat.format("¡Hola {0}!", nombre); | |
} | |
@Override | |
public Mensaje getMensajeJSON(String nombre) { | |
return buildMensaje(nombre); | |
} | |
@Override | |
public Mensaje getMensajeXML(String nombre) { | |
return buildMensaje(nombre); | |
} | |
private Mensaje buildMensaje(String nombre) { | |
return new Mensaje(nombre, "¡Hola mundo!", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); | |
} | |
} |
En el ejemplo se devuelve una clase POJO con varios atributos que usa las anotaciones @XmlRootElement, @XmlElement, @XmlAttribute para indicar los datos y la forma de los datos a generar como resultado:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.resteasy; | |
import javax.xml.bind.annotation.XmlAttribute; | |
import javax.xml.bind.annotation.XmlElement; | |
import javax.xml.bind.annotation.XmlRootElement; | |
@XmlRootElement(name = "mensaje") | |
public class Mensaje { | |
private String nombre; | |
private String mensaje; | |
private String fecha; | |
public Mensaje() { | |
} | |
public Mensaje(String nombre, String mensaje, String fecha) { | |
this.nombre = nombre; | |
this.mensaje = mensaje; | |
this.fecha = fecha; | |
} | |
@XmlElement | |
public String getNombre() { | |
return nombre; | |
} | |
public void setNombre(String nombre) { | |
this.nombre = nombre; | |
} | |
@XmlElement | |
public String getMensaje() { | |
return mensaje; | |
} | |
public void setMensaje(String mensaje) { | |
this.mensaje = mensaje; | |
} | |
@XmlAttribute | |
public String getFecha() { | |
return fecha; | |
} | |
public void setFecha(String fecha) { | |
this.fecha = fecha; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.resteasy; | |
import org.jboss.resteasy.client.ProxyFactory; | |
import org.jboss.resteasy.plugins.providers.RegisterBuiltin; | |
import org.jboss.resteasy.spi.ResteasyProviderFactory; | |
public class HelloWorldResourceClient implements HelloWorldResource { | |
private HelloWorldResource client; | |
public HelloWorldResourceClient() { | |
// Obtener el cliente a partir de la interfaz y de donde está localizado | |
client = ProxyFactory.create(HelloWorldResource.class, "http://localhost:8080/helloworld-resteasy/rest"); | |
} | |
@Override | |
public String getSaluda() { | |
return client.getSaluda(); | |
} | |
@Override | |
public String getSaludaA(String nombre) { | |
return client.getSaludaA(nombre); | |
} | |
@Override | |
public Mensaje getMensajeJSON(String nombre) { | |
return client.getMensajeJSON(nombre); | |
} | |
@Override | |
public Mensaje getMensajeXML(String nombre) { | |
return client.getMensajeXML(nombre); | |
} | |
public static void main(String[] args) { | |
// Inicializacion a realizar una vez por máquina virtual | |
RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); | |
HelloWorldResourceClient client = new HelloWorldResourceClient(); | |
System.out.println(client.getSaluda()); | |
System.out.println(client.getSaludaA("picodotdev")); | |
System.out.println(client.getMensajeJSON("picodotdev")); | |
System.out.println(client.getMensajeXML("picodotdev")); | |
} | |
} |
En el cliente javascript si usamos el formato json nos será más cómodo tratarlo en el navegador:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Ejemplo sencillo de web service con RESTEasy</title> | |
<script type="text/javascript" src="http://localhost:8080/helloworld-resteasy/rest-jsapi"></script> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
alert(HelloWorldResource.getSaluda()); | |
alert(HelloWorldResource.getSaludaA({nombre:'picodotdev'})); | |
alert(HelloWorldResource.getMensajeJSON({nombre:'picodotdev'})); | |
alert(HelloWorldResource.getMensajeXML({nombre:'picodotdev'})); | |
</script> | |
</body> | |
</html> |
Para que el ejemplo funcione deberemos incluir las dependencias org.jboss.resteasy:resteasy-jaxb-provider:2.3.5.Final y org.jboss.resteasy:resteasy-jettison-provider:2.3.5.Final.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
dependencies { | |
compile 'org.jboss.resteasy:jaxrs-api:2.3.5.Final' | |
compile 'org.jboss.resteasy:resteasy-jaxrs:2.3.5.Final' | |
compile 'org.jboss.resteasy:resteasy-jsapi:2.3.5.Final' | |
compile 'org.jboss.resteasy:resteasy-jaxb-provider:2.3.5.Final' | |
compile 'org.jboss.resteasy:resteasy-jettison-provider:2.3.5.Final' | |
providedCompile 'javax.servlet:servlet-api:2.5' | |
} | |
... |
En el siguiente enlace puedes encontrar el código fuente completo de este ejemplo y probarlo tu mismo en un servidor de aplicaciones como Tomcat. La siguiente entrada será como integrar RESTEasy con un framework de desarrollo web como Apache Tapestry.
Referencia:
http://www.jboss.org/resteasy
http://backbonejs.org
Código fuente completo del ejemplo Hola Mundo con RESTEasy