【问题标题】:How to validate request parameters on feign client如何在 feign 客户端上验证请求参数
【发布时间】:2020-01-08 16:57:35
【问题描述】:

有没有办法在请求参数上为 feign 客户端添加验证。

例如:

@FeignClient
public interface ZipCodeClient {
    @GetMapping("/zipcodes/{zipCode}")
    Optional<ZipCodeView> findByZipCode(@PathVariable("zipCode") String zipCode);
}

在向服务器发送 HTTP 调用之前,最好验证 zipcode 不为空且具有特定长度等。

【问题讨论】:

    标签: validation feign


    【解决方案1】:

    如果您的验证很简单,仅适用于标头和查询字符串参数,您可以为此使用RequestInterceptor,因为它使您有机会在将RequestTemplate 发送到Client 之前对其进行审查。

    public class ValidatingRequestInterceptor implements RequestInterceptor {
       public void apply(RequestTemplate requestTemplate) {
          // use the methods on the request template to check the query and values.
          // throw an exception if the request is not valid.
       }
    }
    

    如果需要验证请求正文,可以使用自定义的Encoder

    public class ValidatingEncoder implements Encoder {
       public void encode(Object object, Type type, RequestTemplate template) {
          // validate the object
          // throw an exception if the request is not valid.
       }
    }
    

    最后,如果您想验证单个参数,您可以为参数提供自定义Expander 并在那里进行验证。您可以查看此答案以获取有关如何创建可与 Spring Cloud 一起使用的自定义扩展器的完整说明。

    How to custom @FeignClient Expander to convert param?

    为了完整起见,我提供了一个示例,说明如何使用 vanilla Feign 执行此操作。

    public class ZipCodeExpander implements Expander {
       public String expand(Object value) {
          // validate the object
          // throw an exception if the request is not valid.
       }
    }
    
    public interface ZipCodeClient {
        @RequestLine("GET /zipcodes/{zipCode}")
        Optional<ZipCodeView> findByZipCode(@Param(expander = ZipCodeExpander.class) ("zipCode") String zipCode);
    }
    

    【讨论】:

    • 这很有趣。不幸的是我发现这太依赖 Feign 了;我的想法 - 因为 OP 可能也考虑到他正在使用 @FeignClient,这是一个 Spring Cloud/OpenFeign 注释 - 是能够使用 Spring 实际上支持的 Java Bean Validation (JSR 380) 注释MVC,特别是因为@GetMapping 是一个 Spring Web 注释,可以在此上下文中重用(Spring Cloud/OpenFeign)来定义 HTTP 调用/方法签名。
    【解决方案2】:

    正如this comment 中所指出的,使用 Bean Validation API 的解决方案会很好。事实上,我在一个 Spring Boot 项目中发现,只需在接口上放置 @org.springframework.validation.annotation.Validated 就足以启用 Bean Validation。

    例如:

    @FeignClient
    @Validated
    public interface ZipCodeClient {
        @GetMapping("/zipcodes/{zipCode}")
        Optional<ZipCodeView> findByZipCode(@PathVariable("zipCode") @NotEmpty String zipCode);
    }
    

    在违规情况下触发ConstraintViolationException

    任何标准的 Bean 验证功能都应该在这里工作。

    UDPATE 请注意,此解决方案似乎有一个 potential issue,可能需要像这样设置 Hibernate Validator 配置属性:hibernate.validator.allow_parallel_method_parameter_constraint=true

    【讨论】:

      猜你喜欢
      • 2018-01-05
      • 1970-01-01
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      • 2017-03-08
      • 2016-09-14
      • 1970-01-01
      相关资源
      最近更新 更多