2

I have a webapp (Play framework 2.x, Java) that receives JSON payloads as input.

I have input payloads in different shapes like:

{
  files: [{id: 1,name: null}}
  requiredAttribute: null,
}

I want to output errors in this form, similar to the input:

{
  files: [{name: "name can't be null"}}
  requiredAttribute: "requiredAttribute can't be null",
}

I'd like to know how I can output errors in this form with Java without too much pain.

I know I'll loose the ability to output multiple errors per field and I'm fine with that.

I'm ok using any external library as long as it's easy to declare the constraints on the fields, so using something like Java validation and validation constraints annotations would be nice. But I wasn't able to find any support for this kind of stuff so far. Any idea how it could be done with Play or Java validation or Jackson?

Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • Take a look on [@Valid when creating objects with jackson](https://stackoverflow.com/questions/55457754/valid-when-creating-objects-with-jackson-without-controller). Maybe you could annotate all properties on bean level and validate whether given properties are `not-null` or match other requirements on deserialisation level. Also, solution depends, whether you want to validate `JSON` payload on schema level or on `Java` bean level? See [Validate JSON schema](https://stackoverflow.com/questions/31179086/validate-json-schema-compliance-with-jackson-against-an-external-schema-file) – Michał Ziober May 03 '19 at 12:55

1 Answers1

0

Using bean validation, you can achieve this by calling validate() yourself and processing a collection of Set<ConstraintViolation<T>>.

You first need to get a Validator object. There may be ways to do this better, but one way is to use the factory (used this in the past, it worked with a Hibernate validator dependency on the class path):

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

Then use the validator to retrieve a set of constraint violations (Assuming a generic type T for a bean class with the relevant constraint annotations):

Set<ConstraintViolation<T>> constraintViolations = validator.validate(myBean);

Map<String, String> fieldErrors = new HashMap<>();
for (ConstraintViolation<T> violation : constraintViolations) {
    String message = violation.getMessage();
    String field = violation.getPropertyPath().toString();
    fieldErrors.put(field, message);
}

Note that for nested bean classes, you'll get a dot-separated "path" for field names.

ernest_k
  • 44,416
  • 5
  • 53
  • 99