gpt4 book ai didi

java - jackson 用另一个字段的散列添加自定义字段

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:46:09 27 4
gpt4 key购买 nike

所以,标题基本上描述了我所需要的。比如,要序列化的 bean 看起来像这样:

public class SomeBean {
public String someString;
}

我希望 Jackson 像这样序列化 SomeBean 的一个实例:

{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>'
}

此功能应该是通用的。我不想为 SomeBean 编写特定的序列化程序,因为这需要在多个位置发生。将 '__hash_someString' 添加到类本身不是一个选项,因为它会污染模型。

实现

我希望 Jackson 正常处理 bean。但是当它遇到特定的注释(@GenerateHash)时,它应该像以前一样向对象添加另一个字段。所以它会像这样:

public class SomeBean {
@GenerateHash
public String someString;
}

到目前为止的路

有很多类似的主题,但没有一个尝试过这样的事情。我不是很了解 Jackson Serialization 的内部工作原理,但您似乎只能选择修改整个对象。我还没有找到拦截某个字段序列化过程的方法,只能拦截那个字段的值。

我已经尝试使用 BeanSerializerModifier 来实现它,并且还尝试了一些使用 @Serializer 的方法。但是,我通常会陷入无限循环。

我查阅的资源有(不限于):

简而言之我怎样才能让 jackson 连载

public class SomeBean {
@GenerateHash
public String someString;

public String unaffectedString;
}

为此:

{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>',
unaffectedString: '<some value>'
}

最佳答案

这很有趣。我认为您可以使用 BeanSerializerModifier 解决这个问题。

想法是注册一个自定义序列化器,它可以访问原始 bean 序列化器、属性描述和对象值。如果该属性使用 GenerateHash 注释进行注释,那么序列化程序将发出一个额外的字段。这是一个例子:

public class JacksonGenerateHash {
@Retention(RetentionPolicy.RUNTIME)
public static @interface GenerateHash {
}

public static class Bean {
@GenerateHash
public final String value;

public Bean(final String value) {
this.value = value;
}
}

private static class MyBeanSerializerModifier extends BeanSerializerModifier {
@Override
public JsonSerializer<?> modifySerializer(
final SerializationConfig serializationConfig,
final BeanDescription beanDescription,
final JsonSerializer<?> jsonSerializer) {
return new HashGeneratingSerializer((JsonSerializer<Object>) jsonSerializer, null);
}
}

private static class HashGeneratingSerializer extends JsonSerializer<Object>
implements ContextualSerializer {
private final JsonSerializer<Object> serializer;
private final BeanProperty property;

public HashGeneratingSerializer(
final JsonSerializer<Object> jsonSerializer,
final BeanProperty property) {
this.serializer = jsonSerializer;
this.property = property;
}

@Override
public void serialize(
final Object o,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider)
throws IOException {
serializer.serialize(o, jsonGenerator, serializerProvider);
// if the generatehash is present the property must be set
if (property != null) {
jsonGenerator.writeNumberField("_hash_" + property.getName(), o.hashCode());
}
}
// override this method to access the bean property
@Override
public JsonSerializer<?> createContextual(
final SerializerProvider prov, final BeanProperty property)
throws JsonMappingException {
if (property != null && property.getAnnotation(GenerateHash.class) != null) {
return new HashGeneratingSerializer(serializer, property);
}
return serializer;
}
}

public static void main(String[] args) throws JsonProcessingException {
SimpleModule module = new SimpleModule();
module.setSerializerModifier(new MyBeanSerializerModifier());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.writeValueAsString(new Bean("abc")));
}
}

输出:

{"value":"abc","_hash_value":96354}

关于java - jackson 用另一个字段的散列添加自定义字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25849705/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com