Swagger not scanning ApiModel and ApiModelProperty annotations in entity classes that are in a different jar file

此生再无相见时 提交于 2019-12-07 16:34:41

问题


I have the following two entity classes.

The first class is SampleApiEntity:

package my.company.rest;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hibernate.annotations.Type;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@ApiModel (
    value       = "SampleApiEntity",
    description = "This is a sample entity from the Api package."
)
@Entity
public class SampleApiEntity
        implements Serializable
{
    public SampleApiEntity () {}

    private static final long serialVersionUID = 1L;

    @Column (nullable = false)
    @ApiModelProperty (
        value    = "level",
        required = true
    )
    private Integer   level;

    @Column (length = 255)
    @ApiModelProperty (
        value    = "description"
    )
    private String    description;

    @Column (nullable = false)
    @ApiModelProperty (
        value    = "time",
        required = true
    )
    private Timestamp time;

    @Id
    @Column (
        unique   = true,
        nullable = false
    )
    @Type (type = "pg-uuid")
    @ApiModelProperty (
        value    = "id",
        readOnly = true,
        dataType = "uuid",
        example  = "123e4567-e89b-12d3-a456-426655440000"
    )
    private UUID      sampleApiEntityId;

    public String getDescription ()
    {
        return this.description;
    }

    public Integer getLevel ()
    {
        return this.level;
    }

    public UUID getSampleApiEntityId ()
    {
        return this.sampleApiEntityId;
    }

    public Timestamp getTime ()
    {
        return this.time;
    }

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

    public void setLevel (Integer level)
    {
        this.level = level;
    }

    public void setSampleApiEntityId (UUID sampleApiEntityId)
    {
        this.sampleApiEntityId = sampleApiEntityId;
    }

    public void setTime (Timestamp time)
    {
        this.time = time;
    }
}

The second class is SampleModelEntity:

package my.company.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hibernate.annotations.Type;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

@ApiModel (
    value       = "SampleModelEntity",
    description = "This is a sample entity from the Model package."
)
@Entity
public class SampleModelEntity
        implements Serializable
{
    public SampleModelEntity () {}

    private static final long serialVersionUID = 1L;

    @Column (nullable = false)
    @ApiModelProperty (
        value    = "level",
        required = true
    )
    private Integer   level;

    @Column (length = 255)
    @ApiModelProperty (
        value    = "description"
    )
    private String    description;

    @Column (nullable = false)
    @ApiModelProperty (
        value    = "time",
        required = true
    )
    private Timestamp time;

    @Id
    @Column (
        unique   = true,
        nullable = false
    )
    @Type (type = "pg-uuid")
    @ApiModelProperty (
        value    = "id",
        readOnly = true,
        example  = "123e4567-e89b-12d3-a456-426655440000"
    )
    private UUID      sampleModelEntityId;

    public String getDescription ()
    {
        return this.description;
    }

    public Integer getLevel ()
    {
        return this.level;
    }

    public UUID getSampleModelEntityId ()
    {
        return this.sampleModelEntityId;
    }

    public Timestamp getTime ()
    {
        return this.time;
    }

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

    public void setLevel (Integer level)
    {
        this.level = level;
    }

    public void setSampleModelEntityId (UUID sampleModelEntityId)
    {
        this.sampleModelEntityId = sampleModelEntityId;
    }

    public void setTime (Timestamp time)
    {
        this.time = time;
    }
}

The only difference between the two classes is that they are defined in separate JAR files. SampleApiEntity is packaged in the same JAR as the REST resource class. SampleModelEntity is packaged in a separate JAR with other entity classes. The swagger.yaml file that is generated contains both classes, but lacks information provided by the ApiModel and ApiModelProperty annotations for the SampleModelEntity class.

Here is what I am seeing in the generated swagger.yaml file:

SampleApiEntity:
  type: "object"
  required:
  - "level"
  - "time"
  properties:
    level:
      type: "integer"
      format: "int32"
      description: "level"
    description:
      type: "string"
      description: "description"
    time:
      type: "string"
      format: "date-time"
      description: "time"
    sampleApiEntityId:
      type: "string"
      format: "uuid"
      example: "123e4567-e89b-12d3-a456-426655440000"
      description: "id"
      readOnly: true
  description: "This is a sample entity from the Api package."
SampleModelEntity:
  type: "object"
  properties:
    level:
      type: "integer"
      format: "int32"
    description:
      type: "string"
    time:
      type: "string"
      format: "date-time"
    sampleModelEntityId:
      type: "string"
      format: "uuid"

Can someone help me understand why the ApiModel and ApiModelProperty annotations are not generating output in swagger.yaml?


回答1:


I found the solution. It turned out to be a class loading issue. I had an ear library that I was using to deploy a war library. Both the war and the ear contained a copy of the swagger-annotations artifact. This resulted in loaded annotation classes being different from what was packaged in the ear.

I solved the problem by modifying my pom.xml file for the war library. I added the swagger-annotations as an explicit dependency, and set its scope as provided:

    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-annotations</artifactId>
        <version>1.5.10</version>
        <scope>provided</scope>
    </dependency>

You can find more information here: https://github.com/swagger-api/swagger-core/issues/2582




回答2:


A little hint if you have a multi module maven project and use the maven swagger plugin. The same problem can appear in this constelation.

|-Module1 ( Rest paths )
 |--> pom.xml
|-Module2 ( Models )
 |--> pom.xml
|--> pom.xml ( Parent pom )

Add the plugin to the parent pom and start it from here.

This prevents the class loading problem and the annotations will be recognized and processed in the right way by the swagger "scanner".



来源:https://stackoverflow.com/questions/47777247/swagger-not-scanning-apimodel-and-apimodelproperty-annotations-in-entity-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!