Spring MVC with hibernate Validator to validate single basic type

后端 未结 3 1292
我寻月下人不归
我寻月下人不归 2021-02-19 07:45

Below is the mapped method that I am having trouble with, no matter what value I pass to it the validation returns \"passed validation.\"

@RequestMapping(value          


        
相关标签:
3条回答
  • 2021-02-19 07:50

    No, it is not allowed. I see your point however the JSR-303 specification (which hibernate validator implements) are meant for beans validation, see here

    0 讨论(0)
  • 2021-02-19 08:08

    First, as stated by other answers, Hibernate Validator doesn't allow to validate directly primitives like the example in the question. In order to use Hibernate Validator, defining a new class containing a long value is exactly what is required in order to use Hibernate Validator.

    Second, and most important, whereas programatic validation is something that works and it is quite simple, it is not clean and maintanable. Let me illustrate this with some examples:

    @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";
       }
    }
    

    First thing to notice, is withing 3 simple functions, all the validation code is duplicated.

    Secondly, if at some point your validations requirements change, and now all the long values must be bigger than 35, you need to change every single validation function, and in this example is really simple, because there is only 3 functions with the same validation, but imagine for one moment it is 100 functions where you perform the same validation, now that is painful.

    So just defining a new class, with the long value and the validation annotation, and using that class on every method, you removed code duplication, and also when your validation requirements change, applying changes in one single place, you have mantained the code.

    Also, there is nothing wrong about having to define classes for one specific task, in fact, that is exactly what Single Responsability Principle tells you to do.

    Edit: added a link to a SRP description.

    0 讨论(0)
  • 2021-02-19 08:13

    I am hoping to not have to define an object that only contains a long value just so that I can run validation on it.

    Defining a wrapping bean would IMHO be the smartest move, as hibernate-validator is completly centered around the notion of the bean, and is, after all, a reference implementation of the bean validation specification. One of the primary motivators of the spec is to acknowledge validation as a cross-cutting concern that spans across different app layers, and provide a mechanism to gracefully handle this. That is the reason why it is centered around beans, its the objects that get passed through the layers.

    On the other hand, validating primitves programtically is not a big deal after all, your code can simply be something like

    @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";
      }
    }
    

    So in my opinion, either go for the programatic validation if its simple enough, or simply wrap the value.

    0 讨论(0)
提交回复
热议问题