Java Jackson使用另一个字段的哈希值添加自定义字段
所以,标题基本上描述了我需要什么。 例如,要序列化的bean如下所示:Java Jackson使用另一个字段的哈希值添加自定义字段,java,json,serialization,hash,jackson,Java,Json,Serialization,Hash,Jackson,所以,标题基本上描述了我需要什么。 例如,要序列化的bean如下所示: public class SomeBean { public String someString; } { someString: '<the value>', __hash_someString: '<a proprietary hash of <the value>>' } public class SomeBean { @GenerateHash
public class SomeBean {
public String someString;
}
{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>'
}
public class SomeBean {
@GenerateHash
public String someString;
}
我希望Jackson序列化SomeBean的一个实例,如下所示:
public class SomeBean {
public String someString;
}
{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>'
}
public class SomeBean {
@GenerateHash
public String someString;
}
这条路到目前为止
有很多类似的主题,但没有一个是这样尝试的。我并不真正了解Jackson序列化的内部工作方式,但似乎您只能选择修改整个对象。我没有找到截取字段序列化过程的方法,只有该字段的值
我曾尝试使用BeanSerializerModifier实现这一点,并尝试使用@Serializer进行一些操作。然而,我通常会在一个无限循环中结束
我咨询的资源包括(不限于):
public class SomeBean {
@GenerateHash
public String someString;
public String unaffectedString;
}
为此:
{
someString: '<the value>',
__hash_someString: '<a proprietary hash of <the value>>',
unaffectedString: '<some value>'
}
{
someString:“”,
__散列\u someString:“”,
未受影响的字符串:“”
}
这很有趣。我想你可以用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")));
}
}
工作起来很有魅力!非常感谢。我想我错过了这个,因为我们正在运行一个旧的杰克逊版本(2.0)。立即升级。