【发布时间】:2020-05-21 19:52:43
【问题描述】:
我有一个响应式 WebFlux Spring Boot 应用程序(版本 2.2.3.RELEASE)。我已经定义了一个名为 SearchRequest 的 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);
需要完成一些基本的验证,以及一些可能的转换。 SearchRequest 中的一些字段本身就是对象,例如:
public class SearchRequest {
private Fields fields;
...
}
Fields 类如下所示:
public class Fields {
private Set<String> include;
private Set<String> exclude;
...
}
对于 HTTP POST 请求,用户可以简单地提交一个遵循此结构的 JSON 对象。对于 HTTP GET 请求,我正在处理的 API 规范允许您简单地提供一个 fields URL 参数,其中包含以“+”或“-”为前缀的字段名称数组。我创建了一个扩展 PropertyEditorSupport 的类来解析 URL 参数并填充 Fields 对象的包含和排除集。这是在我的控制器中使用@InitBinder 配置的:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Fields.class, "fields", fieldsPropertyEditor);
}
我的SearchRequest 对象支持使用bbox 值或intersects 值的地理空间查询,但是如果两者都指定,我需要返回400。我尝试了以下方法来实现此验证,但找不到我正在寻找的解决方案:
- 使用
WebDataBinder注册另一个自定义编辑器SearchRequest未指定字段的类。 - 向
WebDataBinder注册验证器(均使用setValidator和addValidators方法)。 - 实现
WebFilter。
解决方案 1 似乎没有效果。编辑器永远不会被调用。在解决方案 2 中,每个请求都会调用 supports 方法,但永远不会调用 validate 方法。解决方案 3 可以工作,但需要我编写两组逻辑——一组用于 GET,一组用于 POST,因为 GET URL 参数与 POST 请求正文分开存储。另外,为了实际检查请求体,exchange.getRequest.getBody() 返回了一个DataBuffer,可以用来将请求体反序列化成一个对象,但是如果没有我之前提到的属性编辑器,我不能直接反序列化成SearchRequest(对于 GET 请求)。
我真的希望找到某种过滤器/转换器/转换器,我可以在之后将请求反序列化为SearchRequest 对象,但在调用控制器处理程序方法之前,但是我似乎找不到这样做的方法。
有人可以告知这是否可行,或者我唯一的选择是在WebFilter 中单独处理 GET/POST 请求吗?
【问题讨论】:
标签: java spring-boot spring-mvc spring-webflux reactor-netty