11

是否有根据参数在 Play Framework 中呈现输出的好方法或正确方法?例子:

对于 HTML:

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

对于 JSON:

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

我认为请求拦截器可以实现这一点,但我不知道如何开始或从哪里开始:-(

或者,也许,写一个render method根据要求读取参数和输出的将军,但这在我看来有点矫枉过正?

4

3 回答 3

20

如果/user/5?v=html/user/5?v=json返回相同资源的两个表示,它们应该是相同的 URL,例如/user/5,根据REST 原则

在客户端,您可以使用Accept请求中的标头来指示您希望服务器向您发送哪种表示形式。

在服务器端,您可以使用 Play 2.1 编写以下代码来测试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();
  }
}

请注意,测试"text/html"应始终在任何其他内容类型之前编写,因为浏览器将Accept其请求的标头设置为*/*匹配所有类型。

如果您不想if (request().accepts(…))在每个操作中编写,您可以将其分解出来,例如如下:

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();
  }
}
于 2012-05-21T13:04:56.023 回答
2

编写 2 个方法,使用 2 个路由(如您未指定,我将使用 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));
}

路线:

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

接下来你可以在其他视图中创建一个链接来显示用户的数据

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

或者是其他东西...

编辑#1

您还可以使用 commonifcase来确定最终输出

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));
}
于 2012-05-20T20:26:59.390 回答
0

我希望用户能够在浏览器中以 html 或 json 的形式查看,因此接受方法对我不起作用。

我通过将通用 renderMethod 放在具有以下样式语法的基类中来解决它

public static Result requestType( )
{
    if( request().uri().indexOf("json") != -1)
    {
        return ok(Json.toJson(request()));
    }
    else 
    {
        return ok("Got HTML request " + request() );
    }
}
于 2012-08-10T06:17:59.533 回答