【问题标题】:CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES not reflected in swagger.jsonCAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES 未反映在 swagger.json 中
【发布时间】:2016-04-05 06:10:45
【问题描述】:

我正在使用 Jersey、Jax-rs 和 swagger(+ 用于注射的 Spring)。我的对象有一些成员和嵌入对象,其名称由多个单词组成,在代码中我使用 camelCase。 我定义了一个解析器,因此它们按照标准约定作为下划线发出。问题是 swagger 显然没有选择这个解析器,因此对象在 swagger json 中仍然显示为 camelCase。

下面是我的具体配置的一些细节:

我的 pom.xml 的片段:

<properties>
        <springframework.version>4.2.3.RELEASE</springframework.version>
        <glassfish.jersey.version>2.22.1</glassfish.jersey.version>
    </properties>
<dependencies>

......

<!-- Jersey -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${glassfish.jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${glassfish.jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>${glassfish.jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${glassfish.jersey.version}</version>
        </dependency>

<!-- swagger documentation -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jersey2-jaxrs</artifactId>
            <version>1.5.0</version>
        </dependency>

.....

</dependencies>

我只使用注释,所以我的 web.xml 是空的,并且我有一个 AppInitializer 类。 Swagger servlet 在类中初始化

public class AppInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(MongoDbConfig.class);
        ctx.register(CORSResponseFilter.class);
        ctx.setServletContext(container);

        container.addListener(new ContextLoaderListener(ctx));
        container.addListener(new RequestContextListener());

        ServletRegistration.Dynamic servlet = container.addServlet("jersey-servlet",
                new org.glassfish.jersey.servlet.ServletContainer());
        servlet.setInitParameter("jersey.config.server.provider.packages", "io.swagger.jaxrs.listing,com.my.server.config,com.my.server.resource");
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/api/*");

        ServletRegistration.Dynamic swagger = container.addServlet("SwaggerServlet",
                new io.swagger.jersey.config.JerseyJaxrsConfig());
        swagger.setInitParameter("api.version", "1.0.0");
        swagger.setInitParameter("swagger.api.basepath", container.getContextPath()+"/api");
        swagger.setLoadOnStartup(2);
    }

}

这是我的主要模型:

import java.io.Serializable;

import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

import io.swagger.annotations.ApiModel;


/**
 * @author Tamar Rosen
 *
 */


@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@ApiModel
public class Property implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;    

    private String id;

    @NotNull
    private String name;

    @NotNull
    private String description;

    private PropertyDetails propertyDetails;

    private int monthlyTax;

    private String schemaUrl;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public PropertyDetails getPropertyDetails() {
        return propertyDetails;
    }

    public void setPropertyDetails(PropertyDetails propertyDetails) {
        this.propertyDetails = propertyDetails;
    }

    public int getMonthlyTax() {
        return monthlyTax;
    }

    public void setMonthlyTax(int monthlyTax) {
        this.monthlyTax = monthlyTax;
    }

    public String getSchemaUrl() {
        return schemaUrl;
    }

    public void setSchemaUrl(String schemaUrl) {
        this.schemaUrl = schemaUrl;
    }

}

在 ContextResolver 类中设置的 CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES。这很好用,只是它没有反映在 swagger 生成的文档中。

下面是 ContextResolver 的实现:

    import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

    private final ObjectMapper mapper;

    public ObjectMapperContextResolver() {
        mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
        );
    }

    public ObjectMapper getContext(Class<?> type) {
        return mapper;
    }
}

我怀疑问题是swagger servlet没有看到上下文解析器,但我不知道如何解决这个问题

【问题讨论】:

  • 您好,您需要为此问题提供更多信息。你的模型是什么样的?能否请您在源代码中发布一个?

标签: java swagger jersey-2.0


【解决方案1】:

好的,谢谢。您是对的,在这种情况下,大摇大摆的内省者无法遵循杰克逊的映射。您可以在每个字段上添加@ApiModelProperty(name = "property_details") 注释,以更改由swagger introspector 解释的名称。

【讨论】:

  • 你打算支持它吗?
  • 这很好,但可能有很多很多不同的路径需要考虑。如果你能找到一种通用的方法(在 swagger-core 中只有一个类可以破解),请发送 PR
【解决方案2】:

Swagger 不使用您为服务配置的对象映射器。 您需要使用以下内容配置 swagger 对象映射器:

...
ApplicationConfig.initializeSwaggerConfiguration(); // call from app config
...

/* Swagger configuratoin */
    @PostConstruct
    public static void initializeSwaggerConfiguration() {
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setSchemes(new String[] { "http" });

        String host = PropertyHandler.getInstance().getValue(PARAM_API_HOST) + ":"
                + PropertyHandler.getInstance().getValue(PARAM_PORT);
        beanConfig.setHost(host);
        beanConfig.setBasePath(PropertyHandler.getInstance().getValue(PARAM_API_BASEPATH));
        beanConfig.setVersion(PropertyHandler.getInstance().getValue(PARAM_VERSION) + " Profile: " + App.getProfile());
        beanConfig.setTitle("SOD Services");
        beanConfig.setDescription("Services for handlign the be");
        beanConfig.setResourcePackage(SERVICES_PACKAGE);
        beanConfig.setScan(true);
        Json.mapper().setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
    }

配置swagger的时候,我的理解是swagger默认使用这个singleton来用在swagger api上。

请注意,您的 Swagger-ui 会中断,因为“basePath”属性也更改为“lower_case_with_underscores”,如下所示:https://github.com/swagger-api/swagger-core/issues/947

我希望这对某人有所帮助 问候

【讨论】:

  • 这根本不能解决问题,是吗?我已经在static 范围内尝试过,但无济于事。如果杰克逊正在序列化对象,这将起作用,但在我感兴趣的一点上,我们正在谈论可能没有以ObjectMapper 的方式序列化的内省值?换句话说,如果ObjectMapper 不在这里发挥作用,那将是有意义的。几乎是@fehguy 的帖子所建议的。现在我不得不对此投反对票。
  • 我认为它确实解决了这个问题。 Swagger 使用 Json.mapper 创建文档,因此,如果您按照我的回答中记录的方式使用,将 camelCase 转换为 snake_case 的问题就可以解决。 swagger.json 将具有预期的值。
猜你喜欢
  • 2014-04-27
  • 2014-09-26
  • 1970-01-01
  • 2020-10-13
  • 2011-11-23
  • 2016-06-21
  • 2021-12-13
  • 1970-01-01
  • 2017-03-24
相关资源
最近更新 更多