2015-12-02 2 views
4

У меня возникли проблемы с документом JAON swagger, созданным с помощью аннотации Java (REST публикуется с использованием Джерси, сериализация обрабатывается джексоном). Глядя на сгенерированный чванство, он включает в себя нулевые значения, которые приводят к сбою интерфейса swagger (у сгенерированного YAML эта проблема отсутствует).Нулевые значения в swagger JSON file

Вот выдержка из 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 
} 

This solution предлагает установить объект картограф, чтобы опустить нулевое значение, чтобы решить эту проблему, но реальность такова, что я не знаю, где и как легко получать доступ к mapper и использование NON_NULL аннотаций в сервисном классе REST бессмысленно. Аналогичный вопрос has been asked, но я не использую Spring (так что у меня нет места, чтобы установить для него настраиваемый картограф или настройки).

В прошлом я использовал Swagger, но с разными настройками конфигурации (в сочетании с подмигиванием, теперь я использую майку), и у меня не было этой проблемы.

В случае, если есть некоторая очевидная расконфигурация, это моя 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 (я всегда путаю с зависимостями чванства):

<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:

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

} 

в идеале я хотел бы иметь переменный ток которую либо вызывают, либо завершают логику swagger (объявляя ее в web.xml), и делает простой mapper.setSerializationInclusion(Include.NON_NULL);, который решает все проблемы, но я не знаю, возможно ли и как это возможно.

+0

Взгляните на ответ в этом вопросе (Обновлено часть): http://stackoverflow.com/questions/33820327/excluding-null -fields-in-pojo-response/33829852 # 33829852 – Ghokun

+0

Я пробовал это, но вместо использования 'ResteasyJackson2Provider' (которого у меня нет) я использовал' io.swagger.jaxrs.json.JacksonJsonProvider'. Во всяком случае, это не работает (код никогда не вызывался), и я подозреваю, что это из-за контекста param 'resteasy.providers' не распознается. Я не знаю, какой параметр использовать (если он существует, я думаю, что решение применяется к ObjectMapper, примененному к службам REST, а не к ответу). – pierpytom

ответ

5

Я потратил неделю на это, и я нашел решение только через несколько часов после того, как я отправил свой вопрос, извините за это.

Похоже, что в web.xml пропускал io.swagger.jaxrs.listing.SwaggerSerializers класс в ServletContainer, полная порция:

<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 укусил все теперь работает, как ожидалось.

2

При использовании spring-boot, вы можете установить в application.yml:

spring.jackson.default-property-inclusion: non_null 
Смежные вопросы