2012-05-20 5 views
11

¿Existe un bueno o una forma adecuada de mostrar la salida en Play Framework dependiendo de un parámetro? Ejemplo:Formato de salida de renderizado (HTML, JSON, XML) según el parámetro?

Para HTML:

http://localhost:9000/user/get/5?v=HTML // should render HTML template 

Para JSON:

http://localhost:9000/user/get/5?v=JSON // should render JSON template 

creo que una solicitud interceptor podría tener la capacidad de lograr esto, pero no tengo ni idea de cómo para comenzar o dónde comenzar :-(

O tal vez, escriba un general render method que lee los parámetros y la salida según lo solicitado, pero esto me parece como un exceso?

Respuesta

20

Si /user/5?v=html y /user/5?v=json regreso dos representaciones de un mismo recurso, que debe ser la misma URL p.ej /user/5, según el REST principles.

En el lado del cliente, puede usar el encabezado Accept en sus solicitudes para indicar qué representación desea que le envíe el servidor.

En el lado del servidor, se puede escribir la siguiente con Play 2.1 para probar el valor de la cabecera Accept:

public static Result user(Long id) { 

    User user = User.find.byId(id); 
    if (user == null) { 
    return notFound(); 
    } 

    if (request().accepts("text/html")) { 
    return ok(views.html.user(user)); 
    } else if (request().accepts("application/json")) { 
    return ok(Json.toJson(user)); 
    } else { 
    return badRequest(); 
    } 
} 

Tenga en cuenta que la prueba contra "text/html" siempre debe ser escrito antes de cualquier otro tipo de contenido ya que los navegadores establezca el encabezado Accept de sus solicitudes en */* que coincida con todos los tipos.

Si no desea escribir el if (request().accepts(…)) en cada acción, puede factorizarlo, p. como la siguiente:

public static Result user(Long id) { 
    User user = User.find.byId(id); 
    return representation(user, views.html.user.ref); 
} 

public static Result users() { 
    List<User> users = User.find.all(); 
    return representation(users, views.html.users.ref); 
} 

private <T> Result representation(T resource, Template1<T, Html> html) { 
    if (resource == null) { 
    return notFound(); 
    } 

    if (request().accepts("text/html")) { 
    return ok(html.apply(resource)); 
    } else if (request().accepts("application/json")) { 
    return ok(Json.toJson(resource)); 
    } else { 
    return badRequest(); 
    } 
} 
+0

bien, creo que me gustaría esta más. Pero, ¿qué tal el enlace a objetos Java basados ​​en formularios HTML o objetos JSON (a partir de solicitudes), también tendría que implementarlos con una instrucción if/else? ¿O servirá 'bindFromRequest' para ambos? – adis

+0

'bindFromRequest' utiliza la cadena de consulta y el cuerpo de la solicitud (que puede ser JSON, forma de url codificada, etc.). –

2

Comentario 2 métodos, utilizar 2 rutas (como no se especifica voy a utilizar muestras de Java:

public static Result userAsHtml(Long id) { 
    return ok(someView.render(User.find.byId(id))); 
} 

public static Result userAsJson(Long id) { 
    return play.libs.Json.toJson(User.find.byId(id)); 
} 

rutas:

/GET /user/get/:id/html  controllers.YourController.userAsHtml(id:Long) 
/GET /user/get/:id/json  controllers.YourController.userAsJson(id:Long) 

siguiente se puede simplemente hacer un enlace en otra vista para visualizar los datos del usuario

<a href="@routes.YourController.userAsHtml(user.id)">Show details</a> 
<a href="@routes.YourController.userAsJson(user.id)">Get JSON</a> 

o alguna otra cosa ...

edición # 1

también se puede utilizar común if o case para determinar el resultado final

public static Result userAsV() { 
    String vType = form().bindFromRequest().get("v"); 

    if (vTtype.equals("HTML")){ 
     return ok(someView.render(User.find.byId(id))); 
    } 

    return play.libs.Json.toJson(User.find.byId(id)); 
} 
+0

Esto podría funcionar, pero la duplicación de la materia no sería mi primera opción. No tengo un caso de uso directo para esto, pero en el futuro, si quisiera hacer una aplicación móvil nativa, me gustaría hacer un pedido para recuperar JSON ... – adis

+0

Bueno, como desee, marque ** editar # 1 * * – biesior

0

quería que el usuario sea capaz de ser visto en el navegador como html o como JSON acepta por lo que el método no funcionó para mí.

lo solucioné poniendo un renderMethod genérica en una clase base con la siguiente sintaxis de estilo

public static Result requestType() 
{ 
    if(request().uri().indexOf("json") != -1) 
    { 
     return ok(Json.toJson(request())); 
    } 
    else 
    { 
     return ok("Got HTML request " + request()); 
    } 
}