【问题标题】:Spring JSR303/349 validation without @Validated没有 @Validated 的 Spring JSR303/349 验证
【发布时间】:2017-09-25 13:45:10
【问题描述】:

我正在使用 jsonschema2pojo 从 json 模式生成 POJO。我想使用 jsr303/349 bean 验证的东西。我在类路径中添加了必要的项目,添加了必要的 bean 来触发验证,但是 jsonschema2pojo 不会将 @org.springframework.validation.annotation.Validated 添加到生成的类中,因此当请求进入我的 Spring Boot 应用程序时不会触发验证。

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

@Validated
class SomeClass extends SomeGeneratedClass {

}

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

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

-- 有帮助的代码

JSON 模式示例:

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

生成的类:

@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'。您可以在 postExample 中按原样使用它。如果您有引用也需要验证的对象的属性,则需要使用“@valid”或“@validated”。在这种情况下,您需要对属性进行注释。
  • 除非我使用带有 @Validated 的类对其进行扩展,否则我的对象不会被验证
  • 另外你会注意到在上面生成的类中,属性上已经有一个@Valid注解
  • 您使用的是什么版本的 Spring Boot?您是否尝试过不使用自定义验证器?
  • 我没有使用自定义验证器。 Spring Boot 1.5.2.RELEASE

标签: java json spring validation jsonschema2pojo


【解决方案1】:

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

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

所以,当 Spring 验证对象时,List userIds 不为空。

这里有两个选择。

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

    私有列表 userIds;

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

【讨论】:

  • 啊,有道理。只需要让 jsonschema2pojo 不初始化集合。现在弄清楚为什么我的 minSize: 1 没有生成适当的注释。谢谢!
【解决方案2】:

您可以使用@Validated 注释ControllerService,而不是对所有需要验证的对象进行注释,如下所示:

@Validated
@Controller
public class Controller {

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

【讨论】:

  • 我已经尝试了所有我能想到的添加@Validated 的组合。我尝试将它放在控制器、方法上,甚至将它添加到RequestBody 上的@Valid 旁边,以及上述的每种组合。验证仍未触发
【解决方案3】:

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

@Autowired
YourValidator validator;

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

    binder.setValidator(validador);

}

在你的端点中

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 2013-08-19
    • 2018-12-02
    相关资源
    最近更新 更多