0

I have a very precise request. Imagine I have the following basic model :

@ValidStudent
public class Student {
    private String firstName;
    private String gender;
    private List<@ValidCourse Course> courses;
}

public class Course {
    private String title;
    private LocalDate date;
    private String level;
}

@ValidCourseis a simple custom annotation which validate a Course object.

In my Spring Boot application there is a custom @ExceptionHandler which returns errors as follow :

{
    "apierror": {
        "status": "BAD_REQUEST",
        "timestamp": "05-03-2020 11:00:09",
        "message": "Validation Error",
        "subErrors": [
            {
                "object": "Student",
                "field": "firstName",
                "rejectedValue": " ",
                "message": "firstName can't be blank. rejected value={" "}"
            },
            {
                "object": "Student",
                "field": "gender",
                "rejectedValue": "FOO",
                "message": "gender has not a valid value. rejected value={FOO}"
            },
            {
                "object": "Student",
                "field": "course[0].level",
                "rejectedValue": "BAR",
                "message": "level has not a valid value. rejected value={BAR}"
            }
        ]
    }
}

Everything seems to work fine BUT if you have a look at the apierror.subErrors[2].object you may notice that the object is "Student" but I want to return "Course" instead. In dept, subError.object is the value of FieldError (package org.springframework.validation) from ObjectError.objectName (same package).

I've already tried to move the @ValidCourse on the Course level class as follow but in this case, the validator is not triggered on POST request when a Student object is send with a List<Course> :

@ValidCourse
public class Course {
        private String title;
        private LocalDate date;
        private String level;
}

I think the easiest solution is to trigger the @ValidCourse on Course class level when a POST request is submit but I can't figure out how to do that :( For now my controller request is :

@PostMapping
public Student addStudent(@RequestBody @Valid Student student){
    return studentService.save(student);
}

EDIT

By adding @Validated at controller class level it validates the List<Course> object with @ValidCourse on class Course level. But, it still returns object: Student as FieldError.objectName :(

EDIT-2 After more research, I'm almost sure that it will be complex configuration to set up. My subError objects are based on org.springframework.validation.FieldError which extends ObjectError from same package. This ObjectError Pojo define the objectName as final String. So there is no setter. Also, in the javadoc getObjectName(): Return the name of the bound root object. In conclusion, I think that it is possible by creating some custom configuration classes but in order to keep my app simple to maintain and wihtout any simple solution I'll not doing anything for that for the moment.

Thanks a lot for your help :)

Pierre Jones
  • 620
  • 1
  • 11
  • 24
  • Have you access to the ConstraintViolation objects? – areus Mar 05 '20 at 22:06
  • 1
    @areus absolutely, I already "customize" it with the following lines of code : ```context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate( String.format("%s %s. rejected value={%s}", field, t, validatedValue)) .addPropertyNode(field) .addConstraintViolation();``` Where field is the name of the rejected field and t is a human readable error message. – Pierre Jones Mar 06 '20 at 09:00

0 Answers0