swagger JSON文件上的空值 [英] Null values on swagger JSON file

查看:99
本文介绍了swagger JSON文件上的空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对通过Java注释生成的JSON swagger文档遇到了一些麻烦(REST使用Jersey公开,序列化由Jackson处理).查看生成的Swagger,它包含 null 值,这些值会导致swagger UI崩溃(生成的YAML没有此问题).

I'm having some trouble with the JSON swagger document generated through Java annotation (REST are exposed using Jersey, serialization is handled by Jackson). Looking at the generated Swagger, it includes null values, which cause the swagger UI to crash (the generated YAML doesn't have this issue).

以下是JSON的摘录:

Here an extract of the JSON:

{
  "swagger": "2.0",
  "info": { "description": null, "version": "1.0.0", "title": "", "termsOfService": null, "contact": null, "license": null },
  "host": "localhost:8080",
  "basePath": "/api",
  "tags": [ { "name": "dataset", "description": null, "externalDocs": null } ],
  "schemes": [ "http" ],
  "consumes": null,
  "produces": null,
  "paths": {
    "/dataset": {
      "get": {
        "tags": ["dataset"],
        "summary": "A dataset",
        "description": "All the available datasets",
        "operationId": "datasetGet",
        "schemes": null,
        "consumes": null,
        "produces": ["application/json"],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Available datasets",
            "schema": {
              "type": "object",
              "format": null,
              "example": null,
              "xml": null,
              "position": null,
              "description": null,
              "title": null,
              "readOnly": null,
              "additionalProperties": {
                "type": "object",
                "format": null,
                "example": null,
                "xml": null,
                "position": null,
                "description": null,
                "title": null,
                "readOnly": null,
                "additionalProperties": {
                  "type": "object",
                  "format": null,
                  "example": null,
                  "xml": null,
                  "position": null,
                  "description": null,
                  "title": null,
                  "readOnly": null,
                  "properties": null
                }
              }
            },
            "examples": null,
            "headers": null
          }
        },
        "security": null,
        "externalDocs": null,
        "deprecated": null
      },
      "head": null,
      "post": null,
      "put": null,
      "delete": null,
      "options": null,
      "patch": null,
      "parameters": null
    }
  },
  "parameters": null,
  "responses": null,
  "externalDocs": null,
  "securityRequirement": null
}

此解决方案建议将对象映射器设置为省略 null 值以解决该问题,但现实情况是我不知道在何处或如何轻松访问该映射器,并且在REST服务类上使用 NON_NULL 注释是没有意义的.也有人问过类似的问题 ,但我不知道'不使用Spring(因此我没有地方设置自定义映射器或为其设置).

This solution suggest to set the object mapper to omit the null value to solve the issue, but the reality is that I don't know where or how to easily access the mapper, and using NON_NULL annotations on the REST service class is pointless. A similar question has been asked as well, but I don't use Spring (so I don't have a place to set a custom mapper or setting for it).

我过去使用Swagger,但是配置设置不同(与wink结合使用,现在我使用的是Jersey),并且没有此问题.

I used Swagger in the past, but with different configuration settings (combined with wink, now I'm using Jersey) and didn't have this issue.

如果有一些明显的错误配置,这是我的 web.xml :

In case there is some obvious misconfiguration, this is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <display-name>MyProject</display-name>

    <!-- Rest services mapping -->
    <servlet>
        <servlet-name>jersey</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>
            io.swagger.jersey.listing.ApiListingResourceJSON,
            org.something.DatasetApi
        </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey</servlet-name>
        <url-pattern>/service/*</url-pattern>
    </servlet-mapping>

    <!-- Swagger config class -->
    <servlet>
        <servlet-name>DefaultJaxrsConfig</servlet-name>
        <servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
        <init-param>
            <param-name>api.version</param-name>
            <param-value>1.0.0</param-value>
        </init-param>
        <init-param>
            <param-name>swagger.api.basepath</param-name>
            <param-value>http://localhost:8080/api</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <!-- Just the CORS filter -->
    <filter>
        <filter-name>ApiOriginFilter</filter-name>
        <filter-class>org.something.ApiOriginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>ApiOriginFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

这是我的pom.xml(我总是对招摇的依赖感到困惑):

And this is my pom.xml (I'm always confused with swagger dependencies):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <groupId>org.something</groupId>
    <artifactId>my_project</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <name>My Project</name>
    <url>http://maven.apache.org</url>

    <build><finalName>MyProject</finalName></build>

    <properties>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.13</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- Required only when you are using JAX-RS Client -->
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <!-- scope>provided</scope -->
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
            <version>2.4.2</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jersey2-jaxrs</artifactId>
            <version>1.5.4</version>
        </dependency>

    </dependencies>


</project>

最后,为了完整起见,这是我的Java类的摘录:

Finally, for completeness, this is an extract of my Java class:

package org.something;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/dataset")
@Produces({ "application/json" })
@Api(value = "/dataset", description = "the dataset API")
public class DatasetApi  {

    private static final Logger log = LoggerFactory.getLogger(DatasetApi.class);

    @GET
    @ApiOperation(value = "All the available datasets.", notes = "Available datasets", response = Map.class, responseContainer = "Map")
    @ApiResponses(value = { @ApiResponse(code = 200, message = "Map of the available datasets", response = Map.class, responseContainer = "Map") })
    public Map<String, String> datasetGet() {
        try {
            log.info("Returning list of dataset");
            return Storage.datasets().getDatasets();
        } catch(Exception e) {
            log.info("Exception!", e);
            throw new WebJsonException(e, Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

}

理想情况下,我想创建一个类,该类可以在之前被调用,也可以包装摇摆逻辑(通过在 web.xml 中声明),并执行一个简单的 mapper.setSerializationInclusion(Include.NON_NULL); 可以解决所有麻烦,但是我不知道这是否可行以及如何实现.

Ideally I'd like to have a class which either is called before or wrap the swagger logic (by declaring it in the web.xml) and does a simple mapper.setSerializationInclusion(Include.NON_NULL); which solves all the troubles, but I don't know if and how this is possible.

推荐答案

我花了一个星期的时间,仅在发布问题几个小时后才找到解决方案,对此感到抱歉.

I've spent a week on that and I found the solution only few hours after I posted my question, sorry for that.

似乎在ServletContainer中的 web.xml 中缺少 io.swagger.jaxrs.listing.SwaggerSerializers 类,整个部分是:

It seems that in web.xml was missing the io.swagger.jaxrs.listing.SwaggerSerializers class in the ServletContainer, the full portion is:

<servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        io.swagger.jersey.listing.ApiListingResourceJSON,
        io.swagger.jaxrs.listing.SwaggerSerializers,
        org.something.DatasetApi
    </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

使用 io.swagger.jaxrs.listing.SwaggerSerializers 可以使所有内容按预期工作.

With the io.swagger.jaxrs.listing.SwaggerSerializers bit everything is now working as expected.

这篇关于swagger JSON文件上的空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆