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

SpringBoot仅对外接口启用Jackson未知字段反序列化失败限制

解决方案:仅对面向客户的控制器请求体启用未知字段校验

要实现仅在面向客户的控制器请求体反序列化时强制执行fail-on-unknown-fields,而其他场景(如调用应用Y的API)忽略未知字段,可以采用以下几种方案,根据实际情况选择:

方案一:在DTO类上直接配置(最简单)

直接在面向客户的DTO类上添加@JsonIgnoreProperties(ignoreUnknown = false)注解,让Jackson反序列化该类时严格校验未知字段,全局Jackson配置保持默认的fail-on-unknown-properties=false(忽略未知字段)即可。

修改你的Product类:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = false)
class Product {
    private int id;
    private String name;
    private int price;

    // 省略getter、setter、构造方法
}

当客户传入包含colour的请求体时,Jackson会抛出UnrecognizedPropertyException,Spring Boot会自动将其转换为400 Bad Request响应,完全符合需求。

这种方式优势是精准控制单个DTO,不会影响其他场景的反序列化(比如调用应用Y的API时使用的其他DTO类,不加该注解就会忽略未知字段)。

方案二:全局拦截面向客户的控制器请求(批量处理)

如果有大量面向客户的控制器和DTO,不想逐个添加注解,可以通过实现RequestBodyAdvice统一为指定包下的控制器请求启用严格校验。

步骤1:创建自定义RequestBodyAdvice

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.io.IOException;
import java.lang.reflect.Type;

// 指定面向客户的控制器所在的包路径
@ControllerAdvice(basePackages = "com.yourproject.controller.client")
public class ClientRequestBodyValidationAdvice extends RequestBodyAdviceAdapter {

    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 只处理JSON类型的消息转换器
        return MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
        // 创建全局ObjectMapper的副本,避免修改全局配置影响其他场景
        ObjectMapper strictMapper = ((MappingJackson2HttpMessageConverter) converterType.getDeclaredConstructor().newInstance()).getObjectMapper().copy();
        // 启用未知字段失败校验
        strictMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
        
        // 替换消息转换器的ObjectMapper为严格校验版本
        MappingJackson2HttpMessageConverter strictConverter = new MappingJackson2HttpMessageConverter(strictMapper);
        return new HttpInputMessage() {
            @Override
            public java.io.InputStream getBody() throws IOException {
                return inputMessage.getBody();
            }

            @Override
            public org.springframework.http.HttpHeaders getHeaders() {
                return inputMessage.getHeaders();
            }
        };
    }
}

说明

  • @ControllerAdvice(basePackages = "...")指定只对该包下的控制器生效,避免影响内部API的控制器。
  • 复制全局ObjectMapper的副本进行修改,确保全局配置不受影响,调用应用Y的API时依然忽略未知字段。

方案三:为控制器单独配置消息转换器

如果需要更细粒度的控制,可以为面向客户的控制器单独配置一个带有严格校验的Jackson消息转换器:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class ClientWebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建严格校验的ObjectMapper
        ObjectMapper strictObjectMapper = new ObjectMapper();
        strictObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
        // 同步全局Jackson的其他配置(如日期格式化、模块注册)
        strictObjectMapper.findAndRegisterModules();

        // 创建自定义消息转换器并优先使用
        MappingJackson2HttpMessageConverter strictConverter = new MappingJackson2HttpMessageConverter(strictObjectMapper);
        converters.add(0, strictConverter);
    }
}

如果只想让该转换器对特定控制器生效,可以结合@ControllerAdvice和RequestMappingHandlerAdapter来注入转换器。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:25:24