为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)。