Java Spring WebFlux筛选器在请求对象反序列化后拦截请求
我有一个反应式WebFlux Spring启动应用程序(版本2.2.3.RELEASE)。我已经定义了一个名为Java Spring WebFlux筛选器在请求对象反序列化后拦截请求,java,spring-boot,spring-mvc,spring-webflux,reactor-netty,Java,Spring Boot,Spring Mvc,Spring Webflux,Reactor Netty,我有一个反应式WebFlux Spring启动应用程序(版本2.2.3.RELEASE)。我已经定义了一个名为SearchRequest的POJO,该POJO用于带注释的控制器中的GET和POST请求: @GetMapping(path = "/search") Mono<ItemCollection> getItems(SearchRequest searchRequest); @PostMapping(value = "/search", consumes = MediaTyp
SearchRequest
的POJO,该POJO用于带注释的控制器中的GET和POST请求:
@GetMapping(path = "/search")
Mono<ItemCollection> getItems(SearchRequest searchRequest);
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<ItemCollection> getItemsPost(@RequestBody SearchRequest searchRequest);
其中,字段
类如下所示:
public class Fields {
private Set<String> include;
private Set<String> exclude;
...
}
我的SearchRequest
对象支持使用bbox
值或intersects
值进行地理空间查询,但是如果两者都指定,我需要返回400。我尝试了以下方法来实现此验证,但找不到我正在寻找的解决方案:
WebDataBinder
注册另一个自定义编辑器
SearchRequest
未指定字段的类李>
WebDataBinder
注册验证器(使用setValidator
和addValidators
方法)WebFilter
supports
方法,但从不调用validate
方法。解决方案3可以工作,但需要我编写两组逻辑——一组用于GET,另一组用于POST,因为GET URL参数与POST请求体分开存储。此外,为了实际检查请求正文,exchange.getRequest.getBody()
返回一个DataBuffer
,可用于将正文反序列化为对象,但如果没有前面提到的属性编辑器(用于GET请求),我无法直接反序列化为SearchRequest
我真的希望找到某种过滤器/转换器/转换器,在请求反序列化为SearchRequest
对象之后,但在调用控制器处理程序方法之前,我可以调用它,但我似乎找不到一种方法来做到这一点
有人能告诉我这是否可行,或者我唯一的选择是在
WebFilter
中单独处理GET/POST请求吗?这不是我想要的答案,但至少目前看来是可行的。基本上,我只是做了一个自定义验证器,并在控制器方法中用@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 {};
}
控制器接口:
@GetMapping(path = "/search")
Mono<ItemCollection> getItems(@Valid SearchRequest searchRequest);
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<ItemCollection> getItemsPost(@Valid @RequestBody SearchRequest searchRequest);
@GetMapping(path=“/search”)
Mono getItems(@Valid SearchRequest SearchRequest);
@PostMapping(value=“/search”,consumes=MediaType.APPLICATION\u JSON\u value)
Mono getItemsPost(@Valid@RequestBody SearchRequest-SearchRequest);
这不是我想要的答案,但至少目前看来是可行的。基本上,我只是做了一个自定义验证器,并在控制器方法中用@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 {};
}
控制器接口:
@GetMapping(path = "/search")
Mono<ItemCollection> getItems(@Valid SearchRequest searchRequest);
@PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<ItemCollection> getItemsPost(@Valid @RequestBody SearchRequest searchRequest);
@GetMapping(path=“/search”)
Mono getItems(@Valid SearchRequest SearchRequest);
@PostMapping(value=“/search”,consumes=MediaType.APPLICATION\u JSON\u value)
Mono getItemsPost(@Valid@RequestBody SearchRequest-SearchRequest);
@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);