1

I'm using the ValidationRulesServlet to generate valdr JSON for my APIs. Currently the generated JSON looks like this:

{
  "Person" : {
    "firstName" : {
      "size" : {
        "min" : 2,
        "message" : "{javax.validation.constraints.Size.message}",
        "max" : 2147483647
      },
      "required" : {
        "message" : "{javax.validation.constraints.NotNull.message}"
      }
    },
    "lastName" : {
      "size" : {
        "min" : 2,
        "message" : "{javax.validation.constraints.Size.message}",
        "max" : 20
      },
      "required" : {
        "message" : "{javax.validation.constraints.NotNull.message}"
      }
    }
  }
}

I'm using Jersey for my REST services and I want the messages in the above JSON to be replaced with values from ValidationMessages.properties.

My ValidationMessages.properties is located in classpath (src/main/resources) and is used correctly by Jackson. This can be confirmed by calling a REST endpoint with an invalid value. Here is an example response:

[
  {
    "message": "Must be between 2 and 2147483647 characters",
    "messageTemplate": "{javax.validation.constraints.Size.message}",
    "path": "PersonServiceImpl.updatePerson.arg0.firstName",
    "invalidValue": ""
  }
]

The corresponding message in my ValidationMessages.properties is

javax.validation.constraints.Size.message = Must be between {min} and {max} characters

How can I get the valdr JSON to output messages from ValidationMessages.properties rather than e.g. {javax.validation.constraints.Size.message}?

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
Kristian S
  • 68
  • 1
  • 7

1 Answers1

1

You can't, at least not out of the box. The reason is pretty obvious if you check the Bean Validation spec or look at the Constraint Javadoc:

Each constraint annotation must host the following attributes:

  • String message() default [...]; which should default to an error message key made of the fully-qualified class name of the constraint followed by .message. For example {com.acme.constraints.NotSafe.message}

So, in essence "message" : "{javax.validation.constraints.Size.message}" in the valdr constraint JSON signifies the message key rather than the actual validation message. It'd IMO be more sensible to call the JSON property messageKey to make this very clear but we wanted to stick with the Bean Validation lingo. In fact, all the properties in the JSON are extracted 1-by-1 from the Bean Validation Constraint.

So, you need a way to display "Must be between 2 and 2147483647 characters" in your AngularJS front-end if the Person.firstName.size constraint is violated. valdr achieves that by integrating well with angular-translate. All you need to do is to make your ValidationMessages.properties available to the front-end and to initialize angular-translate with the messages from that file.

Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
  • I was afraid this was the case. I get your point, but still think it would make sense if Valdr used messages rather than keys whenever defined. With Jersey you can even use the `message` property of `Constraint` as the actual message, e.g. `@Size(min = 2, message = "At least 2 characters")`. I´d love if Valdr used this property in the same way. – Kristian S Dec 28 '15 at 07:26
  • It does. If you define `Constraint#message` in your Java class the message will end up in the valdr JSON instead of the (default) message key. There's no magic, nothing specific to Jersey or valdr, it's just how Java Bean Validation works. We do have a unit test for this at https://github.com/netceteragroup/valdr-bean-validation/blob/master/valdr-bean-validation/src/test/java/com/github/valdr/ConstraintParserTest.java#L86 if you'd like to see code. – Marcel Stör Dec 28 '15 at 13:38