反序列化前的 Spring Boot 验证策略

ejg*_*ald 5 deserialization spring-validator spring-boot jackson2

我正在使用 Spring Boot 来运行 API。我想在反序列化之前验证用户请求参数,以防止 Jackson 抛出反序列化异常。我的想法是最好在没有异常处理的情况下进行验证,但如果您认为我错了,请告诉我。

现在,我制作了一个带有@ControllerAdvice注释的异常处理程序控制器,用于在异常冒泡给用户之前捕获异常,但是有没有办法在杰克逊反序列化之前验证用户输入以检查错误?

我开始尝试使用 spring 验证,但是如果我编写一个自定义验证器并注释请求参数,@Validate验证是否会在反序列化之前进行?春季验证是正确的选择吗?

我研究了使用注释进行验证(JSR 380),但我认为我需要对验证进行更多控制,因此这就是我编写自己的自定义验证器的原因。

我想我可以编写一个自定义反序列化器来调用我的自定义验证器,但这是最好的方法。我正在寻找最佳实践和良好的验证策略。

在此先感谢您的帮助。

Sab*_*han 6

我开始尝试使用 spring 验证,但是如果我编写一个自定义验证器并注释请求参数,@Validate 验证是否会在反序列化之前进行?春季验证是正确的选择吗?

不,验证仅在反序列化后发生,正如 Mark Bramnik 已经回答的那样。您可以通过标准 JSR 验证器或通过 Spring Specific 来完成此操作,它总是在反序列化后发生。

我想我可以编写一个自定义反序列化器来调用我的自定义验证器,但这是最好的方法。我正在寻找最佳实践和良好的验证策略。

这些事情没有标准的策略,一切都根据具体情况而定。有时,您需要自定义验证器,有时则不需要。有时,您需要自定义解串器,有时则不需要。只要尽力满足您的业务需求,其他一切就应该开始顺理成章。

现在有趣的部分,

现在,我制作了一个带有 @ControllerAdvice 注释的异常处理程序控制器,以在异常冒泡给用户之前捕获异常,但是有没有办法在杰克逊反序列化之前验证用户输入以检查错误?

是的。有一种方法叫做json 模式验证(即你有一个 json 模式文件,然后根据它验证你的原始 json ),据我所知,这主要是一个缓慢发展的领域,而且很可能已经死了。我不建议混合 Bean 验证(使用 Jackson、GSON 等反序列化后进行的验证)和模式验证 - 仅选择一个(因为您的代码不应该花费太多时间只进行验证并且目标中有太多重叠两种方法),我想在大多数地方,bean 验证是首选。

模式验证有我能想到的它自己的优点,

1.验证逻辑从 REST 业务逻辑中移出(从控制器、bean 等中移出),并且您的反序列化器始终获得经过验证的 JSON。这样代码看起来更干净。

2.JSON 验证逻辑更改无需重新编译代码即可处理,因为您只需要更新架构文件。使用 Bean 验证,您始终需要重新编译工件。

3.按原样验证原始数据总是比反序列化后验证更准确。JSON 中月份无效的日期字符串可能会被转换为 Java 中的有效日期对象。

4.性能:根据我读到的大多数博客,模式验证比 bean 验证更快。

我不确定为什么它不受欢迎,可能 Spring 的人们让编写验证变得太容易而维护模式很困难:)

请参阅这些 SO QA 和链接以了解更多信息,

如何验证 REST 服务内传入的 JSON 数据?

根据 Java 中的架构验证 JSON

JSON 模式验证工具

Spring REST API 中的 Json 模式验证

通过阅读上面的内容,您可能已经感觉到 JSON 模式验证是通过纯 Java 方式完成的,而不是由 Jackson 或 Spring Boot 支持。


Mar*_*nik 2

Spring Validation 是对 Bean 状态的检查。Bean 类有注释,它们对 Bean 字段值施加了一些约束。

因此,为了调用“验证过程”,bean 应该已经存在。从请求附带的字符串 json/xml 表示创建 bean 正是一个反序列化过程。

因此,答案是 spring 首先使用一些库(例如 jackson)反序列化对象,然后才尝试通过应用验证技术来验证输入。