忽略 Swagger 模型中的未知属性

Ignore Unknown Properties In Swagger Model

我们正在为 restful 服务器和模型使用 Swagger 生成的代码,问题是 json 有效负载可以随时使用新属性更新,这将导致错误。

通常,可以添加 @JsonIgnoreProperties(ignoreUnknown = true) 来忽略属性,但在这种情况下,每次构建都会生成 Swagger 生成的模型(并且是只读的)。

如何设置 Swagger 模型忽略未知属性?

示例错误:

Unrecognized field "abc" (class xyz.model.sample), not marked as ignorable ....

根据 Paul 的回复更新:

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 设置为 false,告诉 Jackson 不要担心未知属性。

@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

如果您使用扫描来注册您的资源和提供者,那么这个 class 应该会自动注册,因为 @Provider 注释。如果你不使用扫描,那么你需要确保你注册了这个解析器,否则它不会被使用。


编辑

如果 Swagger 代码生成器已经在创建 ContextResolver,您可以做的就是在 您的 解析器中实例化它,然后从 ObjectMapper that 解析器,而不是创建您自己的映射器。这确保在生成的解析器中对 ObjectMapper 所做的任何配置仍然有效。然后将 @Priority(Integer.MIN_VALUE) 添加到 class 以保证在生成的那个也被注册的情况下使用它。

@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;
    }
}