配置 Dropwizard ObjectMapper 以配置忽略未知
Posted
技术标签:
【中文标题】配置 Dropwizard ObjectMapper 以配置忽略未知【英文标题】:Configure Dropwizard ObjectMapper for configuration to ignore unknown 【发布时间】:2018-05-20 10:29:41 【问题描述】:使用ObjectMapper
(com.fasterxml.jackson.databind
) 可以指定它应该忽略未知属性。这可以通过在类级别添加@JsonIgnoreProperties(ignoreUnknown = true)
或通过将其设置为映射器中的默认行为来完成。但是,在Application<MyConfiguration>
的initialize()
方法中执行此操作时,似乎没有效果。
ObjectMapper mapper = bootstrap.getObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
对于配置文件中的未知属性,它仍然失败。如何配置 Dropwizard 以忽略未知属性?
【问题讨论】:
DW的版本是多少? 我的版本是0.7.1。显然,较新的版本具有更多实际配置 ModelMapper 的能力,但无论之前的配置是什么,此版本都会在FAIL_ON_UNKNOWN_PROPERTIES
上强制使用 true
标志。
【参考方案1】:
您需要通过以下方式禁用该功能:
bootstrap.getObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
更新:该功能禁用适用于 API 资源,但不适用于配置 YAML。相反,您需要将下面的注释(与问题中提到的相同)添加到配置类中:
@JsonIgnoreProperties(ignoreUnknown = true)
【讨论】:
不,不幸的是,这不起作用。我尝试(1)只禁用和(2)先禁用然后将其配置为false
,但都给了我错误:* Unrecognized field at: blabla Did you mean?: ...
。
我还可以在这里补充一点,我使用的 Dropwizard 版本 (0.7.1) 显然会在 ModelMapper 上强制执行 true
标志,无论您将配置设置为什么。
@Myone 我刚刚测试了在 DW 0.7.1 中禁用此功能,它对我有用。我为此创建了一个简单的应用程序:github.com/andremanuelbarbosa/SOQ47676034
我已经在本地检查了您的代码,虽然禁用该功能不会给您任何错误,但由于我的回答中描述的原因,它也不会产生任何影响。您可以通过将unknown: true
添加到conf.yml
来进行测试,这会导致Myone 提到的错误。
对,这与ConfigurationFactory
在启用FAIL_ON_UNKNOWN_PROPERTIES
之前复制对象映射器的事实一致。这意味着用于 API 序列化的对象映射器不受相同问题的影响。【参考方案2】:
为bootstrap.getObjectMapper()
配置DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
没有达到预期效果的原因是ConfigurationFactory
(稍后用于解析配置的类)在其构造函数中启用了对象映射器的特定功能(请参阅here):
public ConfigurationFactory(Class<T> klass,
Validator validator,
ObjectMapper objectMapper,
String propertyPrefix)
...
this.mapper = objectMapper.copy();
mapper.enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
...
无法直接更改ConfigurationFactory
的行为,但Dropwizard 提供了通过Boostrap.setConfigurationFactoryFactory()
覆盖创建它的工厂ConfigurationFactoryFactory
的方法。这允许用不允许覆盖配置并将其传递给ConfigurationFactory
的代理替换真正的ObjectMapper
:
bootstrap.setConfigurationFactoryFactory(
(klass, validator, objectMapper, propertyPrefix) ->
return new ConfigurationFactory<>(klass, validator,
new ObjectMapperProxy(objectMapper), propertyPrefix);
);
ObjectMapperProxy
的代码在下面忽略启用FAIL_ON_UNKNOWN_PROPERTIES
的尝试:
private static class ObjectMapperProxy extends ObjectMapper
private ObjectMapperProxy(ObjectMapper objectMapper)
super(objectMapper);
private ObjectMapperProxy(ObjectMapperProxy proxy)
super(proxy);
@Override
public ObjectMapper enable(DeserializationFeature feature)
// do not allow Dropwizard to enable the feature
if (!feature.equals(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES))
super.enable(feature);
return this;
@Override
public ObjectMapper copy()
return new ObjectMapperProxy(this);
请注意,除了覆盖 enable
以跳过 FAIL_ON_UNKNOWN_PROPERTIES
之外,copy
也被实现(连同额外的构造函数),因为 ConfigurationFactory
需要对象映射器来支持复制。
虽然上述解决方案有效,但它显然是一种解决方法,我建议升级到更新的 Dropwizard 版本。新的 Dropwizard 使 ObjectMapper
配置更易于覆盖(例如,请参阅 Dropwizard 1.1.x 中的 this Dropwizard commit)。
【讨论】:
以上是关于配置 Dropwizard ObjectMapper 以配置忽略未知的主要内容,如果未能解决你的问题,请参考以下文章
配置 Dropwizard ObjectMapper 以配置忽略未知
dropwizard 应用程序中的配置更改以与 react browserHistory 一起使用