当前位置: 首页 > 知识库问答 >
问题:

Spring WebFlux过滤器在请求对象反序列化之后拦截请求

范兴文
2023-03-14
@GetMapping(path = "/search")
Mono<ItemCollection> getItems(SearchRequest searchRequest);

@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<ItemCollecthtml" target="_blank">ion> getItemsPost(@RequestBody SearchRequest searchRequest);
public class SearchRequest {

    private Fields fields;
    ...
}
public class Fields {

    private Set<String> include;
    private Set<String> exclude;
    ...
}

对于HTTP POST请求,用户可以简单地提交一个遵循此结构的JSON对象。对于HTTP GET请求,我所使用的API规范允许您简单地提供fieldsURL参数,该参数包含一个前缀为“+”或“-”的字段名数组。我创建了一个类,它扩展PropertyEditorSupport,以解析URL参数并填充Fields对象的包含和排除集。这是在我的控制器中使用@initbinder配置的:

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Fields.class, "fields", fieldsPropertyEditor);
}

我的SearchRequest对象支持使用Bbox值或Intersects值进行地理空间查询,但是如果两者都指定,则需要返回400。我尝试了以下方法来实现此验证,但找不到我正在寻找的解决方案:

  1. 使用WebDataBinder为未指定字段的SearchRequest类注册另一个自定义编辑器。
  2. WebDataBinder注册验证器(都使用SetValidatorAddValidator方法)。
  3. 实现WebFilter.

解决方案1似乎没有效果。从不调用编辑器。在解决方案2中,每个请求都会调用supports方法,但从不调用validate方法。解决方案3可以工作,但需要我编写两组逻辑--一组用于GET,一组用于POST,因为GET URL参数与POST请求体分开存储。此外,为了实际检查请求正文,exchange.getrequest.getbody()返回一个databuffer,该databuffer可用于将正文反序列化为对象,但是如果没有前面提到的属性编辑器(用于GET请求),我不能直接反序列化为searchrequest

我真的希望找到某种过滤器/转换器/转换器,在请求被反序列化为SearchRequest对象之后,但在控制器处理程序方法被调用之前,我可以调用这种过滤器/转换器/转换器,但我似乎找不到这样做的方法。

有人能告诉我这是否可能,或者我唯一的选择是在Webfilter中单独处理GET/POST请求吗?

共有1个答案

康文昌
2023-03-14

这不是我要找的答案,但至少现在看来行得通。基本上,我只是创建了一个自定义验证器,并用@valid注释了控制器方法中的SearchRequest参数。

注释:

@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SingleGeometryValidator.class)
@Documented
public @interface SingleGeometry {
    String message () default "Request should not contain both `intersects` and `bbox`. Please choose one geometry to "
            + "search by.";
    Class<?>[] groups () default {};
    Class<? extends Payload>[] payload () default {};
}

验证器:

public class SingleGeometryValidator implements ConstraintValidator<SingleGeometry, SearchRequest> {

    @Override
    public boolean isValid(SearchRequest searchRequest, ConstraintValidatorContext constraintValidatorContext) {
        return !(searchRequest.getBbox() != null && searchRequest.getIntersects() != null);
    }
}
@Data
@SingleGeometry
public class SearchRequest {
...
}
@GetMapping(path = "/search")
Mono<ItemCollection> getItems(@Valid SearchRequest searchRequest);

@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<ItemCollection> getItemsPost(@Valid @RequestBody SearchRequest searchRequest);
 类似资料:
  • 一、拦截请求 mitmproxy的强大功能是拦截请求。拦截的请求将暂停,以便用户可以在将请求发送到服务器之前修改(或丢弃)该请求。mitmproxy的set intercept命令配置拦截。i默认情况下,该命令绑定到快捷方式。 通常不希望拦截所有请求,因为它会不断中断您的浏览。因此,mitmproxy希望将流过滤器表达式作为set intercept选择性拦截请求的第一个参数。在下面的教程中,我们

  • 配置拦截器 declarations: [ AppComponent ], HttpClientModule ], providers: [ [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] bootstrap:

  • 在 imi 中更加推荐使用 AOP 来拦截请求。 不要忘记把 Aspect 类加入 beanScan! Demo <?php namespace ImiApp\ApiServer\Aop; use Imi\RequestContext; use Imi\Aop\Annotation\Around; use Imi\Aop\Annotation\Aspect; use Imi\Aop\Annota

  • 本文向大家介绍解决拦截器对ajax请求的拦截实例详解,包括了解决拦截器对ajax请求的拦截实例详解的使用技巧和注意事项,需要的朋友参考一下 解决拦截器对ajax请求的的拦截 拦截器配置: 1、判断 String XRequested =request.getHeader("X-Requested-With") 的值,目的是判断是否是ajax请求。 2、response.getWriter().wr

  • 我是一些API的客户端,需要在每个请求中发送令牌,为了获得这个令牌,我需要访问发送用户名和密码,并考虑使用请求拦截器来解决这个问题。但是每个请求的用户名和密码是不同的,有一些方法可以在假请求拦截器中使用动态值,或者在每次API调用之前,我需要使用普通的假客户端调用? 我有一个来访问此令牌API 我不确定在构建假客户端以设置每个请求的用户时如何添加这个拦截器

  • 本文向大家介绍详解flutter之网络请求dio,请求,拦截器简单示例,包括了详解flutter之网络请求dio,请求,拦截器简单示例的使用技巧和注意事项,需要的朋友参考一下 flutter一直很火的网络请求插件dio 直接上代码,写成一个类,可以直接使用 包含请求的封装,拦截器的封装 httpHeaders文件则是放一些请求头信息如下 apidomain文件则是放api的地址信息如下 以上就是本