У меня есть объект dto, который поддерживает диапазон IP, используя первое и последнее поля. Простые операции CRUD выполняются с помощью этого класса с помощью dropwizard (валидатор jersey-jackson-hibernate)
public class IpRangeDto {
@JsonCreator
public static IpRangeDto fromCidr(@JsonProperty("cidr") String cidr) {
//Resolve CIDR and assign first and last fields
}
@NotNull
@IpAddress // My custom validator
private String first;
@NotNull
@IpAddress
private String last;
}
Ради удобства пользователя я решил добавить альтернативный способ создания этого объекта, используя CIDR. Таким образом, клиент мог отправлять как first
и last
поле в JSON или только в поле cidr
. Таким образом, способ сделать это, как указано выше, с помощью @JsonCreator. И это работает отлично.
"ipRange":{
"first": "15.0.0.1",
"last": "15.0.0.255",
}
"ipRange":{
"cidr": "15.0.0.0/24"
}
Я хочу проверить это значение CIDR, чтобы оно было правильным, поэтому я могу вернуть 422 с правильным сообщением об ошибке. Если я создаю исключение в методе constructor/factory, то jersey-jackson возвращает 400 напрямую (даже если я выкидываю ConstraintViolationException
, он инкапсулируется JsonProcessingException
).
Я мог бы просто игнорировать исключения и оставить поля пустыми, которые возвратят 422 из-за ограничений @NotNull
но тогда сообщение об ошибке будет не таким ясным, как должно быть.
Я попробовал добавить мой валидатор @Cidr
рядом с параметром @JsonProperty
но это не кажется эффективным. Я понимаю, что валидация происходит после того, как Джексон закончил создание Dtos, поэтому с моим подходом @JsonCreator
не может быть никакого решения этой проблемы. Поэтому я открыт для рефакторинга предложений.
Я не эксперт по точной интеграции проверки Bean в jackson, но я думаю, что это просто проверка действительности. Это означает, что, как вы уже указали, объекты сначала создаются, а затем свойства проверяются.
Проверка Cidr
с версии 1.1) также предлагает так называемую проверку метода, и в этом случае вы можете поместить ограничение Cidr
в строковый параметр метода, но, как сказано, я не думаю, что есть интеграция в jackson для этого,
И еще одна вещь ;-) - статические методы и свойства, как правило, исключаются из проверки в валидации бинов (см. Также http://beanvalidation.org/1.1/spec/#d0e2815).
Что касается обходного пути, то приходит в голову (хотя и немного сложно). Напишите пользовательское ограничение уровня IpRange
класса. В ограничении класса вы получите переданный экземпляр IpRangeDto
и вам IpRangeDto
проверить весь объект и выбрать правильное сообщение об ошибке для любых нарушений. Если вы добавите свойство cidr в dto, которое будет установлено при fromCidr
, у вас будет вся информация, необходимая для проверки и выбора правильного сообщения об ошибке.