Render output format (HTML, JSON, XML) depending on parameter?

前端 未结 3 895
傲寒
傲寒 2020-12-28 09:36

is there a good or proper way to render the output in Play Framework depending on a parameter? Example:

For HTML:

http://lo         


        
相关标签:
3条回答
  • 2020-12-28 10:17

    Write 2 methods, use 2 routes (as you don't specify I will use Java samples:

    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));
    }
    

    routes:

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

    next you can just make a link in other view to display user's data

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

    or something else...

    edit #1

    you can also use common if or case to determine final output

    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 讨论(0)
  • 2020-12-28 10:19

    If /user/5?v=html and /user/5?v=json return two representations of the same resource, they should be the same URL, e.g. /user/5, according to the REST principles.

    On client side, you can use the Accept header in your requests to indicate which representation you want the server to send you.

    On server side, you can write the following with Play 2.1 to test the value of the Accept header:

    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();
      }
    }
    

    Note that the test against "text/html" should always be written prior to any other content type because browsers set the Accept header of their requests to */* which matches all types.

    If you don’t want to write the if (request().accepts(…)) in each action you can factor it out, e.g. like the following:

    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 讨论(0)
  • 2020-12-28 10:26

    I wanted the user to be able to be viewed in the browser as html or as json so the accepts method did not work for me.

    I solved it by putting a generic renderMethod in a base class with the following style syntax

    public static Result requestType( )
    {
        if( request().uri().indexOf("json") != -1)
        {
            return ok(Json.toJson(request()));
        }
        else 
        {
            return ok("Got HTML request " + request() );
        }
    }
    
    0 讨论(0)
提交回复
热议问题