添加TrimString反序列化器后Jackson配置失效,请求字段未被修剪
问题描述
我编写了以下代码实现字符串自动修剪功能,但带有TrimString注解的请求入参字段并未被自动修剪。若直接将模块添加到ObjectMapper中则能正常生效,请问配置存在什么问题?
1. 自定义字符串修剪反序列化器
public class TrimStringDeserializer extends JsonDeserializer<String> implements ContextualDeserializer { @Override public JsonDeserializer<String> createContextual(DeserializationContext ctxt, BeanProperty property) { boolean skip = Optional.ofNullable(property) .map(prop -> prop.getAnnotation(TrimString.class) == null) .orElse(false); if (skip) { return new StringDeserializer(); } else { return this; } } @Override public String deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException { String value = parser.getValueAsString(); if (value != null) { value = value.trim(); } return value; } }
2. Jackson配置类
@Configuration public class JacksonConfig { @Bean Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return builder -> builder.modules(modules -> modules.add(new SimpleModule().addDeserializer(String.class, new TrimStringDeserializer()))); } }
3. TrimString注解
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) public @interface TrimString { }
问题原因与解决方案
核心问题
你通过Jackson2ObjectMapperBuilderCustomizer添加模块的方式有误,导致自定义反序列化器没有被正确注册到Spring管理的ObjectMapper实例中,优先级低于默认的StringDeserializer,无法触发注解对应的修剪逻辑。
解决方案
方案一:将自定义Module注册为Spring Bean
这是Spring环境下注册Jackson模块的标准方式,Spring会自动将模块注入到ObjectMapper中,确保优先级正确:
@Configuration public class JacksonConfig { @Bean public SimpleModule trimStringModule() { SimpleModule module = new SimpleModule(); module.addDeserializer(String.class, new TrimStringDeserializer()); return module; } }
方案二:修正Jackson2ObjectMapperBuilderCustomizer的写法
直接调用modules()方法传入模块实例,而非通过Consumer添加:
@Configuration public class JacksonConfig { @Bean Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { SimpleModule trimModule = new SimpleModule(); trimModule.addDeserializer(String.class, new TrimStringDeserializer()); return builder -> builder.modules(trimModule); } }
额外检查点
确保TrimString注解确实添加到了目标DTO/实体类的字段上,例如:
public class UserRequest { @TrimString private String username; // getter/setter }
内容的提问来源于stack exchange,提问作者GaripTipici
相关产品推荐
相关产品推荐

