如何在反序列化时修改指定注解字段的值(类比Fastjson的ContextValueFilter)
反序列化时修改带指定注解字段的值的实现方案
针对你需求的场景,下面以Fastjson为例给出具体实现方案,同时补充Jackson的实现思路,核心是通过自定义反序列化处理器结合注解判断来修改字段值:
一、Fastjson实现方式
1. 定义自定义注解
首先创建一个标识需要修改字段的注解:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ModifyField { // 可添加参数用于区分不同修改规则,比如规则标识 String rule() default ""; }
2. 实现自定义字段反序列化处理器
继承Fastjson的FieldDeserializer,重写字段解析逻辑,判断字段是否带有@ModifyField注解,若有则修改值:
public class ModifyFieldDeserializer extends FieldDeserializer { public ModifyFieldDeserializer(ParserConfig config, Class<?> clazz, Field field) { super(config, clazz, field); } @Override public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) { ModifyField annotation = this.field.getAnnotation(ModifyField.class); if (annotation != null) { // 解析原始字段值 Object originalValue = parser.parse(); // 根据需求执行值修改逻辑,示例:字符串添加前缀,数字加1 Object modifiedValue = processValue(originalValue, annotation.rule()); // 将修改后的值设置到目标对象或字段映射中 if (object != null) { try { this.field.set(object, modifiedValue); } catch (IllegalAccessException e) { throw new JSONException("Failed to set modified field value", e); } } else { fieldValues.put(this.field.getName(), modifiedValue); } } else { // 无注解则按默认逻辑解析字段 super.parseField(parser, object, objectType, fieldValues); } } private Object processValue(Object originalValue, String rule) { if ("prefix".equals(rule) && originalValue instanceof String) { return "processed_" + originalValue; } if ("plus_one".equals(rule) && originalValue instanceof Integer) { return (Integer) originalValue + 1; } // 默认不修改,返回原始值 return originalValue; } }
3. 注册自定义处理器到Fastjson配置
将自定义处理器注册到全局ParserConfig,让Fastjson在反序列化时自动识别带注解的字段:
// 全局注册自定义字段解析器工厂 ParserConfig globalConfig = ParserConfig.getGlobalInstance(); globalConfig.putDeserializer(Object.class, new FieldDeserializerCreator() { @Override public FieldDeserializer createFieldDeserializer(ParserConfig config, Class<?> clazz, Field field) { return field.isAnnotationPresent(ModifyField.class) ? new ModifyFieldDeserializer(config, clazz, field) : null; } });
4. 测试验证
定义带注解的实体类:
public class User { private String username; @ModifyField(rule = "prefix") private String email; @ModifyField(rule = "plus_one") private Integer age; // getter、setter省略 }
反序列化测试:
String json = "{\"username\":\"zhangsan\",\"email\":\"zhangsan@test.com\",\"age\":25}"; User user = JSON.parseObject(json, User.class); System.out.println(user.getEmail()); // 输出 processed_zhangsan@test.com System.out.println(user.getAge()); // 输出 26
二、Jackson实现思路(补充)
如果使用Jackson,可通过BeanDeserializerModifier全局处理带注解的字段:
- 定义相同的
@ModifyField注解 - 实现自定义
JsonDeserializer处理值修改 - 通过
BeanDeserializerModifier遍历字段,给带注解的字段绑定自定义解析器
示例核心代码片段:
public class ModifyFieldDeserializerModifier extends BeanDeserializerModifier { @Override public List<BeanPropertyDefinition> updateProperties(DeserializationConfig config, BeanDescription beanDesc, List<BeanPropertyDefinition> propDefs) { for (BeanPropertyDefinition propDef : propDefs) { if (propDef.getField().isAnnotationPresent(ModifyField.class)) { JsonDeserializer<?> deserializer = new JsonDeserializer<Object>() { @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Object originalValue = p.getValueAs(Object.class); // 执行修改逻辑 return processValue(originalValue, propDef.getField().getAnnotation(ModifyField.class).rule()); } }; // 给字段绑定自定义解析器 config.addDeserializers(new SimpleDeserializers() {{ addDeserializer(propDef.getType().getRawClass(), deserializer); }}); } } return super.updateProperties(config, beanDesc, propDefs); } }
然后注册到Jackson的ObjectMapper:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new SimpleModule().setDeserializerModifier(new ModifyFieldDeserializerModifier()));
内容的提问来源于stack exchange,提问作者高双龙
相关产品推荐
相关产品推荐

