As I said earlier and following from, you can achieve what you want with the help of the following code:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
public @interface FieldMatch {
String message() default "something is wrong!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String first();
String second();
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
FieldMatch[] value();
}
public static class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object> {
private String firstFieldName;
private String secondFieldName;
@Override
public void initialize(FieldMatch fieldMatch) {
firstFieldName = fieldMatch.first();
secondFieldName = fieldMatch.second();
}
public boolean isValid(Object object, ConstraintValidatorContext constraintContext) {
try {
final Object firstObj = getProperty(object, firstFieldName);
final Object secondObj = getProperty(object, secondFieldName);
if(firstObj == null && secondObj == null || firstObj != null && secondObj != null) {
return false;
}
} catch (final Exception ignore) {
}
return true;
}
private Object getProperty(Object value, String fieldName) {
Field[] fields = value.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(fieldName)) {
field.setAccessible(true);
try {
return field.get(value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return null;
}
}
}
Using:
@FieldMatch.List({
@FieldMatch(first = "name", second = "people"),
@FieldMatch(first = "age", second = "abc")
})
public class Foo {
private String name;
private List<String> people;
private int age;
private Boolean abc;
}
The only difference for you is that you do not want to check if this content is equal only if one field is null and the other is not.
EDIT:
To get an object on your ExceptionHandler, as asked using comments, you simply wrap the exception around the user-defined one and pass the object when you throw it, i.e.
public class CustomException extends Exception {
private String message;
private Object model;
public CustomException(String message, Object model) {
super(message);
this.model = model;
}
public Object getModel() {
return model;
}
}
With this, you can simply do it like this:
@ExceptionHandler(CustomException.class)
public ModelAndView handleCustomException(CustomException ex) {
Object obj = ex.getModel();
}
source
share