【发布时间】:2017-04-05 19:15:58
【问题描述】:
我有一个默认 AbstractJackson2HttpMessageConverter 的 Spring Boot 应用程序。绑定的 Jackson ObjectMapper 实例注册了一个自定义 SimpleModule,因此现在它支持来自 Google Guava 库的 Multimap。
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper()
.setSerializationInclusion(NON_NULL)
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new SimpleModule()
.addSerializer(multimapType, multimapDuplicateKeysSerializer)
.addDeserializer(multimapType, multimapJsonDeserializer)
);
}
假设我的控制器中有以下方法:
@RequestMapping(method = POST)
@ResponseStatus(OK)
public Object post(
@RequestBody final Multimap<String, Object> multimap
) {
...
}
在这一步一切都很好。现在我必须验证多映射是否有空键或空白键,如果在传入的多映射中发现任何无效键,则返回 HTTP 400。这是一个简单的操作,可以很容易地遍历传入的多图并抛出异常以在控制器建议中处理。但这至少有下一个缺陷:
- 我不想直接在我的控制器或相关服务中的某处验证多图。
- 如果这是一个缺陷:我无法使其与 Spring MVC 注释(如
@Valid、@ModelAttribute等)一起使用,但现在我并不真正关心这些,原因如下: - 我不希望在反序列化后验证多映射,因为我想在特定
HttpMessageConverter某处的解析器级别验证传入的请求主体——我需要的验证纯粹是 JSON 流验证即使对于不需要在验证之前反序列化整个多图的大型多图,这也可以完美地工作。如果可能,当然可以。
是否可以仅将特定的HttpMessageConverter 绑定到特定的@RequestBody?大概是这样的:
@RequestMapping(method = POST)
@ResponseStatus(OK)
public Object post(
@SomeMagicSpringAnnotationHere("specificHttpMessageConverter") @RequestBody final Multimap<String, Object> multimap
OR
@AnotherMagicSpringAnnotationHere("specificObjectMapper") @RequestBody final Multimap<String, Object> multimap
OR
@WhateverMagicSpringAnnotationHere @RequestBody final Multimap<String, Object> multimap
) {
...
}
或者我对这种方法有什么误解,它可以通过与 Spring 相关且更优雅的方式来完成?任何建议都非常感谢。提前致谢!
【问题讨论】:
-
只为这种类型实现你自己的自定义
MultiMapHttpMessageConverter,并在你的mvc配置中注册它。 (我什至认为注册它是一个 bean 就足够了,因为HttpMessageConverter实例会被自动检测和注册。 -
@M.Deinum 感谢您的回复。如果我理解它应该如何工作,那么我可能会有两个问题:1)这样的
HttpMessageConverter必须覆盖现有的AbstractJackson2HttpMessageConverter,它现在不能支持多图; 2)它将绑定到整个应用程序中的所有多图,而不是特定的。我是对的,还是我错过了什么? -
为什么要覆盖一个,它会在另一个旁边使用。转换机制检测方法参数的类型并尝试找到合适的转换器。它确实适用于所有
MultiMap参数,您不能只为单个方法/控制器提供一个参数。这不是机制的工作原理。 -
考虑一下,您可以创建一个注释来使用而不是
@RequestBody并实现一个HandlerMethodArgumentResolver来处理这个问题。然后,您可以将另一个注释放在您的参数上,而不是@RequestBody。然后,您可以在该课程中做任何您想做的事情。 -
@M.Deinum 嗯,我试图用
HandlerMethodArgumentResolver进行试验,但由于某种原因无法使其工作(可能是因为参数已经用@RequestBody进行了注释)。我会深入研究一下。
标签: java rest spring-mvc spring-boot