我们将Swagger生成的代码用于一个宁静的服务器和模型,问题是json有效负载可以在任何点使用新属性进行更新,这将导致错误。
通常,可以添加@JsonIgnoreProperties(ignoreUnknown = true)
来忽略属性,但在这种情况下,每次构建都会生成Swagger生成的模型(并且是只读的)。
我们如何设置Swagger模型来忽略未知属性?
示例错误:
Unrecognized field "abc" (class xyz.model.sample), not marked as ignorable ....
更新根据保罗的回应:
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.annotation.Priority;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
@Provider
@Priority(Integer.MIN_VALUE)
public class ObjectMapperResolver implements
ContextResolver<ObjectMapper>{
private ObjectMapper mapper;
public ObjectMapperResolver() {
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
}
@Override
public ObjectMapper getContext(Class<?> cls) {
return mapper;
}
}
使用ContextResolver
全局配置ObjectMapper
。有一个DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
,我们可以设置为假,告诉杰克逊不要担心未知的属性。
@Provider
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {
private ObjectMapper mapper;
public ObjectMapperResolver() {
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public ObjectMapper getContext(Class<?> cls) {
return mapper;
}
}
Jackson JAX-RS提供程序将调用此解析程序以获取用于反序列化的ObjectMapper
。
如果您使用扫描来注册资源和提供程序,则由于@Provider
注释,此类应自动注册。如果您不使用扫描,则需要确保注册此解析程序,否则将不会使用它。
如果Swagger codegen已经在创建ContextResolver
,你可以做的只是在解析器中实例化它,并从该解析器获取ObjectMapper
而不是创建自己的映射器。这可确保在生成的解析器中对ObjectMapper
的任何配置仍然生效。然后在类中添加一个@Priority(Integer.MIN_VALUE)
,以便保证在生成的一个上使用它,如果生成的一个也被注册。
@Provider
@Priority(Integer.MIN_VALUE)
public class ObjectMapperResolver implements ContextResolver<ObjectMapper> {
private ObjectMapper mapper;
public ObjectMapperResolver() {
JSON swaggerResolver = new JSON();
mapper = swaggerResolver.getContext(null);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public ObjectMapper getContext(Class<?> cls) {
return mapper;
}
}