Frage Swagger-codegen generierte Modell-Deserialisierungsprobleme - Unbekanntes Feld "@id"


Ich versuche, den von swagger-codegen generierten Code zu verwenden, um meinen REST-Service zu nutzen, der in meiner swagger.json definiert ist (die auf der Serverseite von springfox 2.9.0 bereitgestellt wird)

Ich erzeuge API, Modelle und unterstützende Dateien.
Aber jedes Mal, wenn ich versuche, eine GET API zu konsumieren, tritt ein Fehler auf:

avax.ws.rs.client.ResponseProcessingException: Problem with reading the data, class xxx.xxx.generatedmodels.MyEntity, ContentType: application/json;charset=UTF-8.
....
Caused by: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "@id" (Class xxx.xxx.generatedmodels.MyEntity), not marked as ignorable

Meine Vermutung ist, dass die generierten Modellklassen die Klassenannotation benötigen @JsonIdentityInfo(generator = JSOGGenerator.class), genau wie sie auf dem serverseitigen Modell sind. (Auch vielleicht @JsonIgnoreProperties(ignoreUnknown = true)?)
Ist diese Annahme richtig? 

Falls ja, gibt es eine Möglichkeit, Swagger-Codegen so zu konfigurieren, dass diese Annotation zu jedem Modell hinzugefügt wird?

Wenn nein, was kann ich tun, damit der ApiClient die empfangene Entität deserialisieren kann?

meine Swagger-Codegen-Konfiguration sieht folgendermaßen aus:

<plugin>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-codegen-maven-plugin</artifactId>
    <version>2.3.1</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>https://example.com/v2/api-docs</inputSpec>
                <language>java</language>
                <generateApis>true</generateApis>
                <generateModels>true</generateModels>
                <generateSupportingFiles>true</generateSupportingFiles>
                <generateModelDocumentation>false</generateModelDocumentation>
                <generateModelTests>false</generateModelTests>
                <modelPackage>xxx.xxx.generatedmodels</modelPackage>
                <apiPackage>xxx.xxx.generatedapi</apiPackage>
                <invokerPackage>xxx.xxx.generatedinvoker</invokerPackage>
                <configOptions>
                    <dateLibrary>java8</dateLibrary>
                    <sourceFolder>src/main/java</sourceFolder>
                    <java8>true</java8>
                </configOptions>
                <library>jersey2</library>
                <output>../generated-client</output>
                <groupId>xxx.xxx</groupId>
                <artifactId>generatedapiclient</artifactId>
                <artifactVersion>1.0.0</artifactVersion>
            </configuration>
        </execution>
    </executions>
</plugin>

Die Antwort sieht in etwa so aus (stark verkürzt. Es gibt viele Objekteigenschaften, die auch "@id" haben. Dieses Beispiel stimmt mit der Datei "swagger.json" weiter unten überein):
{"@id":"1","id":180,"name":"Test entity"}
Der JSON ist gültig, das habe ich überprüft

Bearbeiten: Hier ist mein drastisch reduziert und depersonalisiert swagger.json:

{
  "swagger": "2.0",
  "info": {
    "description": "Api Documentation",
    "version": "1.0",
    "title": "Api Documentation",
    "termsOfService": "urn:tos",
    "contact": {

    },
    "license": {
      "name": "Apache 2.0",
      "url": "http://www.apache.org/licenses/LICENSE-2.0"
    }
  },
  "host": "localhost:9080",
  "basePath": "/",
  "tags": [
    {
      "name": "foobar-controller",
      "description": "REST operations available for FooBar"
    }
  ],
  "paths": {
    "/api/fooBars": {
      "get": {
        "tags": [
          "request-car-controller"
        ],
        "summary": "Find a FooBar by id",
        "operationId": "getBeanUsingGET",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "description": "Authorization",
            "required": true,
            "type": "string"
          },
          {
            "name": "id",
            "in": "query",
            "description": "id",
            "required": true,
            "type": "integer",
            "format": "int64"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/FooBar"
            }
          },
          "401": {
            "description": "Unauthorized"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "security": [
          {
            "token": [

            ]
          }
        ]
      }
    }
  },

  "securityDefinitions": {
    "Authorization": {
      "type": "apiKey",
      "name": "Authorization",
      "in": "header"
    }
  },

  "definitions": {
    "FooBar": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        }
      },
      "title": "FooBar"
    }
  }

Die FooBar-Klasse auf der Serverseite sieht folgendermaßen aus:

@Entity
@Table(name = "foobar")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonIdentityInfo(generator = JSOGGenerator.class) // this is what generates the `@id` in the json. I need this.
public class FooBar implements Serializable {

    private Long id;
    private String name;

    public FooBar(){

    }

    public FooBar(String name){
        this.name = name;
    }

    // getters, setters
}

5
2018-06-21 11:00


Ursprung


Antworten: