¡La versión 2.0 de Play ya está lista! Ayúdanos a traducir la documentación de la útlima versión y sigue nuestro progreso.

Manuales, tutoriales & referencias

Consulte

Contenidos

Elija la versión

Buscar

Busque con google

Libros

Play 1.1 — Cambios de la versión 1.1

Puedes consultar las lista de bugs solucionados en Play 1.1 en la hoja de ruta. Esta página resume los cambios más importantes.

Migrando desde Play 1.0.x

Migrar desde Play 1.0.x es muy simple. No hay cambios en la estructura de directorios de las aplicaciones, de manera tal que la misma aplicación correrá en Play 1.0.3.2 o en Play 1.1. Sin embargo si usas algún módulo externo a tu aplicación, posiblemente tengas que usar alguna versión más reciente que sea compatible con Play 1.1. Consulta la documentación del módulo para más información.

  • Algunas API han sido eliminadas en Play 1.1, luego de haber sido deprecadas en versiones anteriores, pero la mayor parte de las APIs públicas no han sufrido modificaciones. Si te encuentras con algún error de compilación que no sabes cómo resolver, puedes consultar en el grupo de google.
  • El orden de los plugins ha sido cambiado. Si tiene un plugin específico que precisa ejecutar antes o despúes de un plugin por defecto, posiblemente precise cambiar el índice.
  • En play.libs.IO, muchos métodos que solían que solían lanzar excepciones chequeadas (checked exceptions) ahora lanzan excepciones en tiempo de corrda (runtime exceptions). Si la aplicación estaba capturando estas excepciones posiblemente tengas que modifcar la clase de la excepción o dejar de capturarla.
  • En modo producción, la base de datos ya no se modifica automáticamente cuando se modifica el modelo de datos. Si desea este comportamiento, agregue esta línea a su archivo application.conf:
jpa.ddl = update

Nuevo ejecutador de pruebas con un browser sin interfase gráfica (headless browser)

El ejecutador de pruebas de Play requiere un browser web para ejecutar las pruebas. Esto es debido al soporte de pruebas de Selenium, que permite correr las pruebas ejecutando su aplicación en un verdadero browser web.

Sin embargo, a los fines de implementar un servidor de integración continua, se torna difícil ejecutar un browser web real en el servidor de integración. Por eso, desde esta versión, Play incluye un browser independiente sin interfase gráfica (stand-alone headless browser) basado en HtmlUnit.

Cuando ejecute los tests con play auto-test, se utilizará este browser.

Tenga en cuenta que el browser autónomo a ser utilizado intenta emular el comportamiento de Internet Explorer 8, lo cual es bueno ya que como la mayor parte de los desarrolladores usan y prueban sus aplicaciones en browsers como Firefox o Webkit, de esta manera pueden detectar errores obvios de incompatibilidad de JavaScript en sus plataformas de integración.

Nuevo servidor HTTP basado en Netty de JBoss

La versión 1.1 de Play utiliza JBoss Netty en vez de Apache Mina como su servidor HTTP. Esto no debería afectar a su aplicación, y la performance de la capa HTTP debería ser la misma. Sin embargo, este cambio soluciona algunos errores HTTP que afectaban a Play 1.0.x.

Este nuevo servidor HTTP nos permitirá brindar prestaciones HTTP más avanzadas, como la implementación de WebSockets.

Librerías actualizadas y mejoras en las convenciones de nombres

Dado que Play es un stack completo incluye directamente las librerías de JAVA requeridas para su funcionamiento. Todas estas librerías han sido actualizadas, incluyendo la versión 3.5.x de Hibernate que provee soporte para JPA 2.

También hemos adoptado una convención de nombres más adecuada para la inclusión de librerías. Si mira en el directorio framework/lib ahora podrá ver la versión exacta de cada librería en uso.

Nueva API de play.db.Model API independiente de la base de datos

Play introduce la nueva API play.db.Model. Esta API no está pensada para ser utilizada directamente por las aplicaciones, sino que provee una interfase genérica que puede ser implementada por el creador de un módulo para integrar cualquier fuente de datos (incluyendo bases NoSQL).

Esto significa que en Play 1.1, el soporte JPA está totalmente desacoplado del núcleo del framework. Todavía es distribuido como un plug-in por defecto, y se activa atuomátimente si detecta alguna clase anotada como @Entity, pero algunos componentes como CRUD y Fixtures ya no dependen de JPA. Estos componente ahora pueden funcionar directamente con cualquier módulo que provea una implementación de play.db.Model, tales como el módulo play-morphia para MongoDB.

Soporte para Scala

Las librerías del núcleo de framework han sido adaptadas para funcionar con el leguaje Scala. El módulo Scala provee completa integración entre Scala y el framework Play.

Soporte nativo para instalar aplicaciones en servidores Glassfish

Play ahora cuenta con un contenedor nativo para el Servidor de Aplicaciones Glassfish. Esto significa que al agregar agregar el contenedor de aplicaciones Play a cualquer servidor Glassfish puede instalar cualquier aplicación Play en él.

El contenedor para Glassfish está alojado en http://github.com/playframework/play-glassfish, y debería estar próximamente disponible directamente en el repositorio contrib de Glassfish.

Debido a que Glassfish permite ejecutar varias aplicaciones simultáneamente, ahora podrá ejecutar múltiples aplicaciones en una única JVM.

Tenga en cuenta que esto difiere de empaquetar su aplicación como un archivo WAR. El contenedor de aplicaciones Play para Glassfish ejecuta las aplicaciones nativamente: no utiliza un contenedor de Servlets, y no requiere que empaquete su aplicación de un modo en particular.

Soporte de Hosts virtuales en las rutas HTTP

El archivo routes ahora soporta hosts virtuales. Esto puede resultar de utilidad si los parámetros de acciones deben ser extraidos del parámetro del host. Por ejemplo, para una aplicación SAAS, podría usar:

GET    {client}.mysoftware.com/         Application.index

y luego, automáticamente obtener el valor del parámetro client de la misma manera en que lo hace para cualquier otro parámetro:

public static void index(String client) {
    ...
}

Al utilizar la anotación @@{...} (ruteo inverso absoluto) en un template, el host será utilizado si es provisto por la correspondiente ruta. Esto puede resultar de suma utilidad en diversos escenarios.

Por ejemplo, si desea utilizar una red de distribución de contenidos para distribuir sus contenidos estáticos, podría escribir un archivo routes como este:

#{if Play.mode.isDev()}
    GET     /public/                        staticDir:public
#{/}
#{else}
    GET     assets.myapp.com/               staticDir:public
#{/}

Y luego en sus templates:

<img src="@@{'/public/images/logo.png'}">

Lo cual será invertido como http://locahost:9000/public/images/logo.png en modo desarrollo, y http://assets.myapp.com/images/logo.png en modo producción.

Soporte para vinculación personalizada

El sistema de vinculación ahora soporta mayores capacidades de personalización.

@play.data.binding.As

La nueva anotación @play.data.binding.As permite configurar de qué manera se vincularán los parámetros de acuerdo al contexto. Puede utilizarlo, por ejemplo, para especificar el formato de fechas a ser utilizado por DateBinder:

public static void update(@As("dd/MM/yyyy") Date updatedAt) {
    ...
} 

La anotación @As también provee soporte para internacionalización de aplicaciones. Significa que usted puede brindar una anotación específica para cada configuración regional:

public static void update(
        @As(
            lang={"fr,de","en","*"}, 
            value={"dd/MM/yyyy","dd-MM-yyyy","MM-dd-yy"}
        )
        Date updatedAt
    ) {
    ...
}

La anotación @As puede funcionar con todos las clases de vinculación (binders) que la soportan, incluyendo sus propias clases de vinculación. Por ejemplo, utilizando ListBinder:

public static void update(@As(",") List<String> items) {
    ...
}

Este ejemplo víncula un String con una cadena de texto separada por comas con una List.

@play.data.binding.NoBinding

La nueva anotación @play.data.binding.NoBinding permite establecer aquellos campos que no serán vinculados, a fin de resolver potenciales problemas de seguridad. Por ejemplo:

public class User extends Model {   
    @NoBinding("profile") public boolean isAdmin;
    @As("dd, MM yyyy") Date birthDate;
    public String name;
}
 
public static void editProfile(@As("profile") User user) {
    ...
}

En este caso, el campo isAdmin nunca será vinculado a partir de la acción editProfile, incluso si algún usuario malicioso incluye un campo user.isAdmin=true en un post fraudulento.

play.data.binding.TypeBinder

La anotación @As también le permite definir una clase de vinculación (binder) completamente personalizado. Tan sólo debe especificar una clase que herede de TypeBinder. Por ejemplo:

public class MyCustomStringBinder implements TypeBinder<String> {
 
    public Object bind(String name, Annotation[] anns, String value, Class clazz) {
        return "!!" + value + "!!";
    }
 
}

Lo puede utilizar en cualquier acción, de la siguiente manera:

public static void anyAction(@As(binder=MyCustomStringBinder.class) String name) {
    ...
}

@play.data.binding.Global

Tambien puede definir clases de vinculación globales, que se aplicarán a todos los datos del correspondiente tipo. Por ejemplo, para vincular todos los datos del tipo java.awt.Point:

@Global
public class PointBinder implements TypeBinder<Point> {
 
    public Object bind(String name, Annotation[] anns, String value, Class class) {
        String[] values = value.split(",");
        return new Point(
            Integer.parseInt(values[0]), 
            Integer.parseInt(values[1])
        );
    }
    
} 

Como puede ver, se trata tan sólo de una clase de vinculación anotada con @play.data.binding.Global. Un módulo externo puede proveer clases de vinculación a un proyecto, permitiendo de esta manera reutilizar estos componentes.

Nueva librería para el consumo de servicios web de manera asincrónica

La librería play.libs.WS permite a su aplicación comportarse como un cliente web. En esta versión incluimos una nueva implementación asincrónica basada en en la librería AsyncHttpClient. Esta nueva implementación provee un nuevo método xxxAsync que le permite consumir servicios web remotos de manera asincrónica.

Al combinarlo con la orden waitFor(…), puede utilizarse para desarrollar aplicaciones de alta performance, no bloqueantes, que integren información (mash-up) de otras aplicaciones existentes:

public static void mirrorFeed() throws Exception {
    if (request.isNew) {
        Future<HttpResponse> feed = WS.url(
            "http://planet.playframework.org/feed"
        ).getAsync();
        request.args.put("futureFeed", feed);
        waitFor(feed);
    } else {
        HttpResponse res = (
            (Future<HttpResponse>)request.args.get("futureFeed")
        ).get()
        renderXml(res.getXml());    
    }
}

Soporte para OAuth

La nueva librería play.libs.OAuth provee soporte para el protocolo OAuth. OAuth es un protocolo abierto que brinda una API para implementar autorización de usuarios para aplicaciones web de una manera simple y estandarizada.

Una nueva aplicación de ejemplo, twitter-oauth, demuestra el uso de esta API al conectarse de manera segura utilizando la API de twitter.

Soporte para HTTPS

El servidor HTTP provisto por play ahora soporta el protocolo HTTPS. Por supuesto que puede implementarlo en producción si lo desea. Brinda soporte para la adminsitración de certificados, ya sea a través del clasico keystore de JAVA o utilizando simples archivos cert y key. Para iniciar un conector HTTPS para su aplicación, simplemente incluya la propiedad https.port en su archivo application.conf:

http.port=9000
https.port=9443

Tendrà que poner sus certificados en el directorio conf. Play brinda soporte para certificados X509 y certificados keystore. Los certificados X509 deben tener el sigueinte nombre:
host.cert para el certificado y host.key para la clave. Si estuviera utilizando keystore, por defecto debería llamarse keystore.jks.

Si usa certificados X509, los siguientes parámetros pueden configurarse a través del archivo application.conf:

# X509 certificates
certificate.key.file=host.key
certificate.file=host.cert
# In case your key file is password protected
certificate.password=secret

Tenga en cuenta que estos son los valores por defecto.

Puede generar certificados auto-firmados utilizando openssl:

openssl genrsa 1024 > host.key
openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert

Si está utlizando el keystore de java, entonces las siguientes propiedades pueden ser configuradas en el archivo application.conf:

# Keystore 
ssl.KeyManagerFactory.algorithm=SunX509
trustmanager.algorithm=JKS
keystore.password=secret
keystore.file=certificate.jks

Estos son los valores por defecto.

Nuevas prestaciones del Cache

Hay dos nuevas prestaciones que facilitan el uso del cache para acciones y templates. Ahora puede guardar en el cache el resultado de una acción con la anotación @play.cache.CacheFor. Esto es sumamente útil para páginas seudo-estáticas:

@CacheFor("1h")
public static void index() {
    render();
}

También hay un nuevo tag, #cache, que le permite fácilmente guardar en el cache fragmentos de templates:

<h1>Very complex home page to build</h1>
 
#{cache 'home-' + connectedUser.email, for:'15min'}
    ...
#{/cache}

Estas nuevas prestaciones utilizan el mismo cache estándar de Play

Los archivos WAR están completamente precompilados

El comando play precompile ahora compila toda la aplicación a bytecode de Java. Esto significa que puede distribuir una aplicación de Play totalmente compilada, y que puede eliminar todos los archivos de la carpeta app/, incluyendo los templates.

Todos los archivos WAR generados por el comando**play war** se compilan ahora de manera automática.

Por defecto, cuando ejecuta una aplicación Play siempre verificará el código fuente de la aplicación para detectar cambios. Si simplemente quiere que su aplicación se inicie del código precompilado, puede especificar la propiedad del sistema precompiled=true:

play start myApp -Dprecompiled=true

Argumentos de enrutamiento global

Ahora, con play.mvc.Controller.routeArgs puede definir argumentos que serán utilizados globalmente para cualquier inversión de enrutamiento. Por ejemplo, si tiene un parámetro que es común a múltiples rutas:

GET     /{lang}/            Application.index
GET     /{lang}/users       Application.users
GET     /{lang}/items       Application.items

Puede omitir el parámetro lang para cada acción, y encargarse de él aplicando un único filtro @Before:

@Before
static setLang(String lang) {
    Lang.set(lang);
    routeArgs("lang", lang);
}

Al agregar el argumento lang mediante routeArgs, éste será automáticamente utilizado al invertir enrutamientos, aún cuando no sea especificado:

<a href="@{Application.users()}">Users list</a>

será invertido como:

<a href="/fr/users">Users list</a>

Más flexibilidad para escribir comandos personalizados

Los desarrolladores de módulos tienen ahora más flexibilidad para escribir comandos personalizados de Python. El archivo commands.py agregado por un módulo puede interactuar con cualquier otro comando existente. Además, los comandos agregados por un módulo aparecen ahora listados por el comando play help.

Otras mejoras menores

También hay una cantidad impresionante de pequeñas mejoras y nuevas prestaciones, así como 230 bugs corregidos, incluyendo:

  • Soporte para namespaces en la librería play.libs.XPath library
  • Soporte para el valor never en la programación de Tareas
  • Los tipos de datos Mime para servir recursos estáticos pueden ahora ser definidos en application.conf
  • Funciones de soporte para evitar cross-domain XHR en play.mvc.Http.Response
  • Soporte para cookies HTTPOnly
  • Nuevo comando play check para buscar nuevas versiones del framework Play