deamon
deamon

Reputation: 92377

Returning validation errors as JSON with Play! framework

I want to build an application where forms are submitted via Ajax without a complete page reload. To display server-side validation errors the server should return validation errors as JSON and an appropriate HTTP status (400).

How can I accomplish this with the Play! framework?

Upvotes: 8

Views: 4586

Answers (4)

Robin Raju
Robin Raju

Reputation: 1315

To perform server side validation of your request, Play framework provides a builtin validation module which uses Hibernate Validator under the hood.

Assuming you have a POJO class corresponding to the incoming request,

import play.data.validation.Constraints;
    public class UserRequest{       
    @Constraints.Required
    private String userName;

    @Constraints.Required
    private String email;
}

The request validation can be performed from controller as follows.

public class UserController extends Controller{
Form<UserRequest> requestData = Form.form(UserRequest.class).bindFromRequest();
    if(requestData.hasErrors()){
        return badRequest(requestData.errorsAsJson());
    } else{
        //... successful validation
    }
}

The following response will be produced if the request fails the validation.

{
  "userName": [
    "This field is required"
  ],
  "email": [
    "This field is required"
  ]
}

In addition to this, you can apply multiple Constraints to the class fields. Some of them are,

  • @Constraints.Min()
  • @Constraints.Max()
  • @Constraints.Email

Upvotes: 6

leonidv
leonidv

Reputation: 1412

In Play Framework 2.x and Scala you can use this example:

import play.api.libs.json._

case class LoginData(email : String, password: String)

implicit object FormErrorWrites extends Writes[FormError] {
  override def writes(o: FormError): JsValue = Json.obj(
    "key" -> Json.toJson(o.key),
    "message" -> Json.toJson(o.message)
  )
}

val authForm = Form[LoginData](mapping(
  "auth.email" -> email.verifying(Constraints.nonEmpty),
  "auth.password" -> nonEmptyText
  )(LoginData.apply)(LoginData.unapply))

def registerUser = Action { implicit request =>
 authForm.bindFromRequest.fold(
  form => UnprocessableEntity(Json.toJson(form.errors)),
  auth => Ok(Json.toJson(List(auth.email, auth.password)))
 )
}

I see that question is labeled with java tag, but I suppose this maybe useful for Scala developers.

Upvotes: 7

Codemwnci
Codemwnci

Reputation: 54884

Look at the samples-and-tests folder and the validation application. One of the examples (Sample7), does exactly what you are after, using a custom tag called jQueryValidate (which you can see in the sample).

If you try the sample, you will see that it is quite a neat solution, and in my opinion, this validation method should be part of the Core Playframework.

Upvotes: 4

Tommi
Tommi

Reputation: 8608

Are you looking for something more complex than this:

public static void yourControllerMethod() {
    ... // your validation logic

    if (validation.hasErrors()) {
       response.status = 400;
       renderJSON(validation.errors);
    }
}

Upvotes: 6

Related Questions