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

Spring Boot 2.4.5如何为指定目录控制器配置独立Jackson ObjectMapper?

解决方案:Spring Boot 针对指定包控制器配置差异化JSON序列化

针对Spring Boot 2.4.5项目中,需要统一com.xxx.controller.agent目录下控制器的JSON返回格式(不影响旧控制器)的需求,以下是具体实现方案:

核心思路

利用Jackson的自定义序列化器,结合Spring MVC的消息转换器匹配规则,为指定包下的控制器单独配置JSON序列化逻辑,实现差异化输出。

具体实现步骤

1. 自定义BigDecimal序列化器

针对代理控制器的需求,将BigDecimal序列化为去掉末尾0的字符串:

public class AgentBigDecimalSerializer extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }
        // 去除末尾无效0并转为字符串
        String formattedValue = value.stripTrailingZeros().toPlainString();
        gen.writeString(formattedValue);
    }
}

2. 注册自定义Jackson模块

将自定义序列化器封装为Jackson模块,便于统一管理:

public class AgentJacksonModule extends SimpleModule {
    public AgentJacksonModule() {
        super("AgentCustomModule");
        // 注册BigDecimal自定义序列化器
        addSerializer(BigDecimal.class, new AgentBigDecimalSerializer());
        // 可在此添加其他类型的自定义序列化/反序列化规则
    }
}

3. 配置包专属消息转换器

通过WebMvcConfigurer扩展消息转换器,让自定义规则仅对com.xxx.controller.agent包下的控制器生效:

@Component
public class AgentJsonConverterConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 创建专属代理控制器的JSON转换器
        MappingJackson2HttpMessageConverter agentConverter = new MappingJackson2HttpMessageConverter();
        
        // 复制Spring Boot默认ObjectMapper配置,避免丢失原有序列化规则
        ObjectMapper agentObjectMapper = new ObjectMapper();
        agentObjectMapper.copyProperties(new ObjectMapper());
        
        // 注册自定义模块
        agentObjectMapper.registerModule(new AgentJacksonModule());
        
        agentConverter.setObjectMapper(agentObjectMapper);
        agentConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
        
        // 设置匹配规则:仅处理指定包下的控制器请求
        agentConverter.setMatcher(new RequestMatcher() {
            @Override
            public boolean matches(HttpServletRequest request) {
                HandlerMethod handlerMethod = (HandlerMethod) request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
                if (handlerMethod == null) {
                    return false;
                }
                // 判断控制器类是否在目标包下
                return handlerMethod.getBeanType().getPackageName().startsWith("com.xxx.controller.agent");
            }
        });
        
        // 将自定义转换器优先级设为最高,优先处理匹配的请求
        converters.add(0, agentConverter);
    }
}

备选方案:基于@ControllerAdvice的局部配置

如果代理模块有独立的DTO类,也可以通过@ControllerAdvice为指定包的控制器统一绑定序列化规则:

@ControllerAdvice(basePackages = "com.xxx.controller.agent")
public class AgentJsonAdvice {

    @Bean
    public MappingJackson2HttpMessageConverter agentJacksonConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.copyProperties(new ObjectMapper());
        mapper.registerModule(new AgentJacksonModule());
        converter.setObjectMapper(mapper);
        return converter;
    }
}

注意事项

  • 必须复制默认ObjectMapper的配置,否则会丢失Spring Boot原生的Jackson规则(如日期格式化、空值处理等)。
  • 测试时需分别验证代理控制器和旧控制器的返回格式,确保BigDecimal等类型的序列化结果符合预期。
  • Spring Boot 2.4.x版本需使用extendMessageConverters扩展转换器,避免使用configureMessageConverters替换所有默认转换器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 06:04:53