gpt4 book ai didi

java - Spring MVC : Is it possible to bind a specific HttpMessageConverter to a @RequestBody-annotated parameter?

转载 作者:行者123 更新时间:2023-11-29 07:30:42 25 4
gpt4 key购买 nike

我有一个带有默认 AbstractJackson2HttpMessageConverter 的 Spring Boot 应用程序。绑定(bind)的 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)
);
}

假设我的 Controller 中有以下方法:

@RequestMapping(method = POST)
@ResponseStatus(OK)
public Object post(
@RequestBody final Multimap<String, Object> multimap
) {
...
}

在这一步一切都很好。现在我必须验证 multimap 的空键或空白键,如果在传入的 multimap 中发现任何无效键,则返回 HTTP 400。这是一个微不足道的操作,可以很容易地遍历传入的多映射并抛出一个异常以在 Controller 建议中处理。但这至少有下一个缺陷:

  • 我不想直接在我的 Controller 或相关服务中的某处验证多图。
  • 如果它是一个缺陷:我无法让它与 @Valid@ModelAttribute 等 Spring MVC 注释一起工作,但现在我真的不关心这些,因为以下原因:
  • 我不希望在反序列化后验证多图,因为我想在特定 HttpMessageConverter 某处的解析器级别验证传入的请求正文——我需要的验证是纯粹的 JSON 流验证,即使对于不需要在验证之前反序列化整个多图的大型多图也能完美工作。如果可能的话,当然可以。

是否可以仅将特定的 HttpMessageConverter 绑定(bind)到特定的 @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 相关且更优雅的东西来实现吗?非常感谢任何建议。提前致谢!

最佳答案

创建一个专门的注释,即 @MultiMapRequestBody

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MultiMapRequestBody {

boolean required() default true;

然后创建一个 MultiMapRequestBodyMethodArgumentResolver,它知道该做什么。

public class MultiMapRequestBodyMethodArgumentResolver implements HandlerMethodArgumentResolver {

public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(MultiMapRequestBody.class); // maybe check argument type too.
}

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// Logic for validation and converting using Jackson
// Take a look at MappingJackson2HttpMessageConverter

}
}

现在您可以自己处理正文转换和验证。您可能想查看 MappingJackson2HttpMessageConverter,以获取有关如何读取和解析正文的一些灵感。或者可以扩展用于参数转换的 abstract 类之一。

现在在您的请求处理方法中使用 @MultiMapRequestBody 而不是 @RequestBody 注释。

@RequestMapping(method = POST)
@ResponseStatus(OK)
public Object post(
@MultiMapRequestBody final Multimap<String, Object> multimap
) {
...
}

关于java - Spring MVC : Is it possible to bind a specific HttpMessageConverter to a @RequestBody-annotated parameter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43239795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com