Spring JSR303/349 没有@Validated 的验证

Spring JSR303/349 validation without @Validated

我正在使用 jsonschema2pojo 从 json 模式生成 POJO。我想使用 jsr303/349 bean 验证工具。我将必要的项目添加到 class 路径,添加了必要的 beans 来触发验证,但是 jsonschema2pojo 不会将 @org.springframework.validation.annotation.Validated 添加到生成的 classes 等当请求进入我的 spring 启动应用程序时,验证不会被触发。

我能够通过像这样写一个空的 class 并将 @RequestBody 类型更改为新类型来确认我的验证器设置正确:

@Validated
class SomeClass extends SomeGeneratedClass {

}

当我这样做时,验证按预期工作。但是,我们正在查看数十个(如果不是可能的话)一百个或更多的这些扩展对象,并且其中有一堆是湿代码(IE,而不是 DRY)的缩影,因此这作为解决方案并不理想。

所以我的问题是:如果有问题的对象没有用 @Validated 注释,有没有办法在传入请求中触发 spring 中的 bean 验证?请注意,jsonschema2pojo 目前对 Spring 没有依赖关系,我发现作者不太可能接受添加一个的拉取请求。

-- 有帮助就打码

示例 JSON 模式:

{
  "type": "object",
  "properties": {
    "userIds": {
      "type": "array",
      "items": { "type": "string" },
      "minSize": 1
    }
  },
  "additionalProperties": false,
  "required": ["userIds"]
}

生成class:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "userIds"
})
public class ExampleSchema {

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    @Valid
    @NotNull
    private List<String> userIds = new ArrayList<String>();

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    public List<String> getUserIds() {
        return userIds;
    }

    /**
     * 
     * (Required)
     * 
     */
    @JsonProperty("userIds")
    public void setUserIds(List<String> userIds) {
        this.userIds = userIds;
    }

    public ExampleSchema withUserIds(List<String> userIds) {
        this.userIds = userIds;
        return this;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(userIds).toHashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof ExampleSchema) == false) {
            return false;
        }
        ExampleSchema rhs = ((ExampleSchema) other);
        return new EqualsBuilder().append(userIds, rhs.userIds).isEquals();
    }
}

我的 WebConfig 中的验证 bean 设置:

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(LocalValidatorFactoryBean validator) {
        final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator);

        return methodValidationPostProcessor;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }

还有我的控制器方法:

@RequestMapping(value = "", method = RequestMethod.POST)
public void postExample(@RequestBody @Valid ExampleSchema example) {
    //Perform actions on validated object
}

您可以用 @Validated 注释 ControllerService 而不是对所有需要验证的对象都这样做,如:

@Validated
@Controller
public class Controller {

    @RequestMapping(value = "", method = RequestMethod.POST)
    public void postExample(@RequestBody @Valid ExampleSchema example){
       //Perform actions on validated object
    }
}

在您的 class 中,您在同一行中定义和实例化数组。

private List<String> userIds = new ArrayList<String>();

因此,当 Spring 验证对象时,List userIds 不为空。

这里有两个选择。

  1. 您可以删除 userIds 的实例化。

    私有列表 userIds;

  2. 您可以更改验证。您可以使用 @Size(min=1) 代替 @NotNull,也可以同时使用它们。你也可以使用 @NotEmpty 但你需要休眠验证器。

像这样在你的控制器中创建一个 initbinder:

@Autowired
YourValidator validator;

@InitBinder()
protected void initBinder(WebDataBinder binder) {

    binder.setValidator(validador);

}

并且在您的端点

public OrdenServicioTo guardarOrden(@ModelAttribute("dto")@Validated @RequestBody Object dto)
{
    ///YOurCode
}