java - 使用类字段中指定的自定义反序列化器反序列化字符串

标签 java serialization jackson

我需要编写一个方法,该方法接受一些对象、存在于给定对象类中的一些字段名 fieldName,以及一些字段值 value。该值是字段的 JSON 序列化形式。该方法应获取该值并相应地对其进行反序列化,如下所示:

static void setField(Object obj, String fieldName, String value) throws Exception {
    Field field = obj.getClass().getDeclaredField(fieldName)
    Object valObj = objectMapper.readValue(value, field.getType());
    field.set(obj, valObj);
}

(我实际上只需要检索反序列化的值,而不是再次设置它,但这使它成为一个更好的例子。) 只要 jackson 的默认反序列化就足够了,它就可以工作。现在假设我有一个带有自定义(反)序列化器的类:

class SomeDTO {
    String foo;
    @JsonSerialize(using = CustomInstantSerializer.class)
    @JsonDeserialize(using = CustomInstantDeserializer.class)
    Instant bar;
}

一种可能的解决方案是手动检查 JsonDeserialize 注释。但是,我真的不想尝试复制 Jackson 遵循的任何政策来决定使用什么序列化程序,因为这看起来很脆弱(例如全局注册的序列化程序)。

是否有使用 DTO 类中定义的字段的反序列化配置反序列化值的好方法?也许在将字段的注释传递给 Jackson 的同时将值反序列化为字段的类型,以便他们得到尊重?

我设法获得了一个 AnnotatedMember 实例,它包含所有必需的信息(JSON 注释和反射字段 - 或 setter/getter-access),但无法弄清楚如何由于缺少文档,我会用它来反序列化独立值:

final JavaType dtoType = objectMapper.getTypeFactory().constructType(SomeDTO.class);
final BeanDescription description = objectMapper.getDeserializationConfig().introspect(dtoType);
for (BeanPropertyDefinition propDef: beanDescription.findProperties()) {
    final AnnotatedMember mutator = propertyDefinition.getNonConstructorMutator();
    // now what? Also: How do I filter for the correct property?
}

最佳答案

一种可能是序列化对象,替换给定的字段,然后再次反序列化。当从/到 JsonNode 而不是 JSON-String 序列化时,这可以很容易地完成,如下所示:

static Object setField(Object obj, String fieldName, String value) throws Exception {
    // note: produces a new object instead of modifying the existing one
    JsonNode node = objectMapper.valueToTree(obj);
    ((ObjectNode) node).put(fieldName, value);
    return objectMapper.readValue(node.traverse(), obj.getClass());
}

但是,仅仅为了反序列化单个字段而对整个对象进行序列化和反序列化似乎开销很大,而且可能很脆弱,因为 DTO 类的其他方面会影响单个字段的反序列化过程

关于java - 使用类字段中指定的自定义反序列化器反序列化字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52428246/

相关文章:

java - 如何在 Jackson 中获取 "JAX-B-like"XMLRootElement 类名包装器

java - POST 到 Spring MVC Controller 结果为 "HttpMessageNotReadableException: Could not read JSON: No suitable constructor found"

spring - 如何将 jackson objectmapper dateformat 配置添加到 spring mvc 配置中?

java - 有没有办法用 xPath 获取节点值而不需要这种丑陋的翻筋斗?

java - 我有一个 dd-mon-yyyy 格式的日期(字符串),我想将此日期与系统日期进行比较

使用FOR lOOP时java堆内存使用异常

java - 如何将可序列化对象写入字符串而不写入文件?

python - 带有python中键值对列表的配置文件

java - 使用 Jackson 将字符串转换为对象

java - 为什么错了?关于 Java 8 流式处理