Spring MVC с hibernate Validator для проверки единого базового типа

Ниже представлен сопоставленный метод, с которым у меня возникают проблемы, независимо от того, какое значение я передаю ему, валидация возвращает "пройденную проверку".

@RequestMapping(value = "test", method = RequestMethod.POST)
@ResponseBody
public String getTest(@RequestBody @Valid @Max(32) long longValue, BindingResult result) {
  if (result.hasErrors()) {
    return "failed validation";
  } else {
    return "passed validation";
  }
}

Я знаю, что @Max работает с моим приложением, потому что я использую его для проверки на пользовательских объектах, которые возвращают большое количество данных контроллеру. Он не выполняет проверку в этом случае, когда я вызываю @Valid и тип проверки объекта в параметрах метода.

Не разрешено ли это с помощью hibernate-validator?

Я надеюсь не определять объект, который содержит только длинное значение, так что я могу выполнить проверку на нем.

Ответы

Ответ 1

Я надеюсь, что не нужно определять объект, который содержит только длинный значение, чтобы я мог выполнить проверку на нем.

Определение обертывания bean будет IMHO самым умным движением, поскольку hibernate-validator полностью сосредоточен вокруг понятия bean и, в конце концов, является эталонной реализацией спецификации валидации bean. Одним из основных мотивов спецификации является подтверждение валидации как сквозной проблемы, которая охватывает разные уровни приложений, и обеспечивает механизм для грамотного управления этим. Именно поэтому он сосредоточен вокруг beans, его объектов, которые проходят через слои.

С другой стороны, проверка программных примитивов в конечном счете не является большой проблемой, ваш код может просто быть чем-то вроде

@RequestMapping(value = "test", method = RequestMethod.POST)
@ResponseBody
public String getTest(@RequestBody long longValue, BindingResult result) {
  if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
    return "failed validation";
  } else {
    return "passed validation";
  }
}

Итак, по моему мнению, либо пойти на программную проверку, если ее достаточно просто, либо просто обернуть значение.

Ответ 2

Нет, это запрещено. Я вижу вашу точку зрения, однако спецификация JSR-303 (которая реализует валидатор гибернации) предназначена для проверки beans, см. здесь

Ответ 3

Во-первых, как утверждают другие ответы, Hibernate Validator не позволяет проверять непосредственно примитивы, как пример в вопросе. Чтобы использовать Hibernate Validator, определение нового класса, содержащего длинное значение, является именно тем, что требуется для использования Hibernate Validator.

Во-вторых, и самое главное, тогда как программная валидация - это то, что работает, и это довольно просто, она не чиста и не поддерживается. Позвольте мне проиллюстрировать это несколькими примерами:

@RequestMapping(value = "testA", method = RequestMethod.POST)
@ResponseBody
public String getTestA(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test A";
   } else {
     return "passed validation for test A";
   }
}


@RequestMapping(value = "testB", method = RequestMethod.POST)
@ResponseBody
public String getTestB(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test B";
   } else {
     return "passed validation for test B";
   }
}


@RequestMapping(value = "testC", method = RequestMethod.POST)
@ResponseBody
public String getTestC(@RequestBody long longValue, BindingResult result) {
   if (longValue > 32) {
     result.rejectValue("longValue", "error.longValue", "longValue max constrained failed");
     return "failed validation for test C";
   } else {
     return "passed validation for test C";
   }
}

Прежде всего, обратите внимание, что с тремя простыми функциями весь код проверки дублируется.

Во-вторых, если в какой-то момент ваши требования к проверке изменяются, и теперь все длинные значения должны быть больше 35, вам нужно изменить каждую функцию проверки, и в этом примере это действительно просто, потому что есть только 3 функции с та же проверка, но представьте, что на мгновение это 100 функций, где вы выполняете ту же проверку, теперь это болезненно.

Таким образом, просто определяя новый класс с длинным значением и аннотацией проверки и используя этот класс для каждого метода, вы удаляете дублирование кода, а также когда ваши требования к проверке изменяются, применяя изменения в одном месте, вы поддерживаете код.

Кроме того, нет ничего плохого в том, что нужно определять классы для одной конкретной задачи, на самом деле это именно то, что принцип единой ответственности сообщает вам сделать.

Изменить: добавлена ​​ссылка на описание SRP.