我想启用一些字符串类型字段的自定义 jackson 反序列化器。反序列化器还需要注入(inject)一个基于 guice 的依赖 bean。示例代码如下:
public class CustomDeserializer extends StdDeserializer<String> {
private SomeDependecy dependency;
public StringDeserializer() {
this(null);
}
public StringDeserializer(Class<?> vc) {
super(vc);
}
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return dependency.perform(p.getValueAsString());
}
}
我无法注册基于类类型的模块,因为它是通用的(String.class、复杂数据类型(但不是每个都需要自定义反序列化器))。有没有办法不使用静态方法来实现上述目标?
PS:我搜索了网络,但没有使用 statics 找不到更干净的解决方案。所有关于使用一些静态方法获取上下文和 bean 的建议。
最佳答案
看起来还有另一种方法(感谢我的一位同事)在 objectMapper 实例上使用 injectableValues,然后通过 DeserializationContext ctxt 获取依赖项。以下是代码。
ObjectMapper 向导模块。
public class MerchantConverterModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
@Singleton
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
/**
* Add dependency object to object mapper.
*/
objectMapper.setInjectableValues(new InjectableValues
.Std()
.addValue("DependencyName", dependency));
return objectMapper;
}
}
自定义反序列化器的代码
public class CustomDeserializer extends StdDeserializer<String> {
private SomeDependecy dependency;
public StringDeserializer() {
this(null);
}
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return getDependency(ctxt).perform(p.getValueAsString());
}
private SomeDependency getDependency(DeserializationContext ctxt) {
SomeDependency dependency = (SomeDependency) ctxt
.findInjectableValue("DependencyName", null, null);
return dependency;
}
}
findInjectableValue
方法是 final方法,因此您可能需要调整单元测试代码以模拟 final方法。
注意:缺点是对象映射器和反序列化器之间存在紧密耦合。
关于java - 如何将依赖项注入(inject) Jackson 自定义反序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54777586/