You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3如何忽略Content-Type处理JSON请求?

解决方案

问题1:无视Content-Type解析JSON并保留验证注解功能

最可靠的方式是自定义HttpMessageConverter,扩展Spring默认的MappingJackson2HttpMessageConverter,让它支持所有媒体类型(包括无Content-Type的请求)。这样Spring会优先使用这个转换器解析请求体为JSON,同时完全保留@RequestBody、@Valid、@NotNull等注解的验证功能。

具体实现代码:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
        // 设置支持所有媒体类型,覆盖默认的仅application/json限制
        jacksonConverter.setSupportedMediaTypes(Arrays.asList(
                MediaType.ALL,
                MediaType.APPLICATION_JSON,
                MediaType.TEXT_PLAIN,
                MediaType.APPLICATION_FORM_URLENCODED
        ));
        // 将自定义转换器放在列表最前面,确保优先被使用
        converters.add(0, jacksonConverter);
    }
}

配置后,无论请求的Content-Type是text/plain、application/x-www-form-urlencoded还是为空,Spring都会用Jackson将请求体解析为JSON并映射到RequestDto,同时自动触发验证注解的校验逻辑。


问题2:全局/针对特定端点配置

  • 全局生效:上面的WebConfig就是全局配置,所有使用@RequestBody的POST端点都会无视Content-Type解析JSON。
  • 针对特定端点:可以通过自定义注解+参数解析器实现,只对指定接口生效:
  1. 定义自定义注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonAnyContentType {
}
  1. 配置自定义参数解析器:
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter customJacksonConverter = new MappingJackson2HttpMessageConverter();
        customJacksonConverter.setSupportedMediaTypes(Arrays.asList(MediaType.ALL));
        converters.add(customJacksonConverter);
    }

    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter(ObjectProvider<HttpMessageConverter<?>> messageConverters) {
        RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
        List<HttpMessageConverter<?>> converters = messageConverters.orderedStream().collect(Collectors.toList());
        
        RequestResponseBodyMethodProcessor customProcessor = new RequestResponseBodyMethodProcessor(converters) {
            @Override
            public boolean supportsParameter(MethodParameter parameter) {
                // 仅对带有@JsonAnyContentType注解的方法生效
                return super.supportsParameter(parameter) &&
                       parameter.getMethod().isAnnotationPresent(JsonAnyContentType.class);
            }
        };
        
        adapter.setMessageConverters(converters);
        adapter.setHandlerMethodArgumentResolvers(Collections.singletonList(customProcessor));
        return adapter;
    }
}
  1. 在目标端点上添加注解:
@PostMapping("/custom-endpoint")
@JsonAnyContentType
public ResponseEntity<?> handleCustomRequest(@Valid @RequestBody RequestDto dto) {
    // 业务逻辑
    return ResponseEntity.ok(dto);
}

问题3:最优方案

自定义HttpMessageConverter是最优解,原因如下:

  • 完全保留@RequestBody的原生特性:包括自动参数映射、验证注解触发、统一异常处理(比如JSON解析错误会抛出HttpMessageNotReadableException,可以通过@ControllerAdvice统一处理)。
  • 代码侵入性低:不需要修改控制器方法的参数结构,也不需要手动解析请求体或实现验证逻辑。
  • 符合Spring生态:基于Spring MVC的扩展机制实现,稳定性和维护性更高。

之前的Filter方案失效的原因是:Spring在进入Filter之前就已经根据原始Content-Type选择了对应的消息转换器,后续修改头信息无法改变已选择的转换器;而自定义转换器是直接修改了转换器的支持范围,从根源上解决了问题。

内容的提问来源于stack exchange,提问作者Snow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:51:17