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
相关产品推荐
相关产品推荐

