当前位置: 首页 > 知识库问答 >
问题:

如何封闭响应实体的主模板响应在斯瓦格?

荆鸿畅
2023-03-14

我的问题与贴在这里的问题有关。

我不得不重新表述我的问题,因为我觉得前面的问题太冗长了。再来一次!

我有一个REST API,它返回一个资产列表,它是这样编码的:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAllAssets() {
        List<Asset> assets = new ArrayList<Asset>();
        for(int i=1; i<11; i++) {
            assets.add(new Asset(i));
        }

        return RestResponse.create(Status.OK, "10 assets Fetched successfully!", assets);
    }

它产生的反应是这样的:

{
    "message":"10 assets Fetched successfully!",
    "content": [{
        "id":"1",
        "type":"LPTP",
        "owner":"Ram",
        "serialNo":"WDKLL3234K3",
        "purchasedOn":"01 Jan 2017"

    },
    {
        "id":"2",
        "type":"LPTP",
        "owner":"Ram",
        "serialNo":"WDKLL3234K3",
        "purchasedOn":"01 Jan 2017"

    },
    ...
    ]
}

我有60多个服务在我的应用程序遵循相同的响应模板:

{
        "message":"Message the service wants to send to the client",
        "content": {
            ....
            Entity returned by the service
            ....
        }
}

以下是代表我们响应模板的RestResponse POJO:

 public class RestResponse {
        private String message;
        private Object content;

        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public Object getContent() {
            return content;
        }
        public void setContent(Object content) {
            this.content = content;
        }

        private RestResponse(String message, Object content) {
            this.message = message;
            this.content = content;
        }

        public static Response create(Response.Status status, String message, Object content) {
            return Response.status(status).entity(new RestResponse(message, content)).build();
        }
}

现在,我们使用Swagger记录所有API,遇到了一个问题。

由于我们将为所有API返回response类,因此我为我的操作编写了以下注释:

@ApiOperation(value="Fetches all available assets", response=RestResponse.class, responseContainer="List")

Swagger所做的是在RestResponse类的定义模式中,如下所示:

"definitions": {
    "RestResponse": {
      "type": "object",
      "properties": {
        "message": {
          "type": "string"
        },
        "content": {
          "type": "object"
        }
      }
    }
 }

在这里,我没有得到关于内容属性中对象属性的任何信息或模式。

我知道这是因为斯瓦格不适用于通用对象。

因此,如果我将我的@ApiOperation注释更改为以下注释:

@ApiOperation(value="Fetches all available assets", response=Asset.class, responseContainer="List")

在上面的例子中,Swagger描述了资产实体的属性,但显然,消息属性(我的响应模板)缺失。

我的问题是我想两者兼得。我的响应模板的content属性可以是任何实体。

所以,我可以设置response=Asset。类并指示Swagger在对其进行记录之前,将资产封装到Response内容属性中?或者我可以通过其他方式实现这一点?

希望这次我能准确无误!

谢谢,斯里拉姆·斯里达兰。

编辑——在我尝试了Marc Nuri的建议后,我创建了一个类似的RestServiceResponse。使用泛型对象初始化,并将my@ApiOperationRestServiceResponse属性设置为RestServiceResponse

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": ""
  },
  "host": "localhost:7070",
  "basePath": "/assets/rest",
  "tags": [
    {
      "name": "Assets"
    }
  ],
  "schemes": [
    "http"
  ],
  "paths": {
    "/assets/{id}": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Fetches information about a single asset",
        "description": "",
        "operationId": "fetchAssetDetail",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "$ref": "#/definitions/RestServiceResponse<Asset>"
            }
          }
        }
      }
    }
  }
}

如您所见,定义部分完全缺失。我错过什么了吗?

我有我的项目在GitHub,以防你需要看到整个代码。请帮我。


共有2个答案

陈奇希
2023-03-14

再次感谢马克·努里!

我可能已经找到了一个适合我的场景的解决方案。我就是这么做的。我的RestServiceResponse类与我的问题(最近的编辑)中提到的类相同,我只是通过添加一个static final类来修改AssetService类,如下所示:

private static final class AssetResponse extends RestServiceResponse<Asset> {
        private Asset data;
}

完成后,我将我的@ApiOperation注释更改为:

@ApiOperation(value="Fetches an asset by ID", produces="application/json", response=AssetResponse.class)

现在,这基本上做的是,为了纯粹的留档目的,它似乎只是在编译期间用特定的Asset类型替换RestService响应类中的Generic Type,以便Swagger可以定义对象。

现在,当我运行Swigger JSON URL时,我得到了一个完美的文档!

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": ""
  },
  "host": "localhost:7070",
  "basePath": "/assets/rest",
  "tags": [
    {
      "name": "Assets"
    }
  ],
  "schemes": [
    "http"
  ],
  "paths": {
    "/assets/{id}": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Fetches information about a single asset",
        "description": "",
        "operationId": "fetchAssetDetail",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "$ref": "#/definitions/AssetResponse"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Asset": {
      "type": "object",
      "required": [
        "name",
        "owner",
        "purchaseDate",
        "type"
      ],
      "properties": {
        "id": {
          "type": "integer",
          "format": "int32",
          "description": "The internal unique ID of the Asset"
        },
        "name": {
          "type": "string",
          "description": "Name of the asset"
        },
        "type": {
          "type": "string",
          "description": "Name of the asset",
          "enum": [
            "Laptop",
            "Desktop",
            "Internet Dongle",
            "Tablet",
            "Smartphone"
          ]
        },
        "owner": {
          "type": "string",
          "description": "ID of the person who owns this asset"
        },
        "purchaseDate": {
          "type": "string",
          "format": "date",
          "description": "Date when this asset was purchased"
        }
      }
    },
    "AssetResponse": {
      "type": "object",
      "properties": {
        "message": {
          "type": "string"
        },
        "content": {
          "$ref": "#/definitions/Asset"
        }
      }
    }
  }
}

我还不知道这是否是可能的最有效的解决方案,但现在对我来说已经足够好了。请分享你的想法。

司马晋
2023-03-14

我们在微服务响应中使用了类似的结构。

唯一的区别是,我们的响应容器(即,response)没有原始类型,并为消息正文/内容使用类型参数。

请尝试将您的Rest响应更改为:

public class RestResponse<T> {
    private String message;
    private T content;

    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getContent() {
        return content;
    }
    public void setContent(T content) {
        this.content = content;
    }

    private RestResponse(String message, T content) {
        this.message = message;
        this.content = content;
    }

    public static <T> Response create(Response.Status status, String message, Object content) {
        return Response.status(status).entity(new RestResponse(message, content)).build();
    }
}

然后像这样注释endpoint:

 @ApiOperation(
            value="Fetches all available assets",
            responseReference = "RestResponse<List<Asset>>")

对于最新版本的“招摇过市”来说,这是可行的。

 类似资料:
  • 我有一个方法,调用一个endpoint来发布客户我怎么才能只得到消息"EMAIL ALREADY EXISTS"从响应体的Rest模板,以便在FacesContext中显示它 这是回应机构

  • 我使用Spring Rest模板时,我的应用程序中的rest Web服务。在测试中,代码工作得很好,但是在正式生产环境中,我的cpde不工作,因为身体回来是空的 我尝试了以下方法 我在测试中得到的响应如下 在生产过程中,resp是 返回的响应主体为空。我知道nginx版本不同,但这超出了我的控制范围 我们非常感谢你的任何帮助 干杯Damien

  • 我可以使用toEntity()方法返回ResponseEntity,如下所示: 但是我想在返回之前处理响应头。上面的代码将WebClient响应转换为响应实体并立即返回,但我想将其存储在响应实体变量中,处理它,然后返回响应实体。 我提到了这个- 当我试图将其存储在varibale中时,我遇到了这个错误-

  • 问题内容: 我正在发出HTTP请求并侦听“数据”: 问题在于响应是分块的,因此“数据”只是发送回的一部分内容。 我如何将全身退回? 问题答案:

  • 问题内容: 反向代理是可行的。如何获得响应主体? 问题答案: 有一个领域。您可以使用它来修改响应。例如: 整个场景的操场示例:http : //play.golang.org/p/b0S5CbCMrI。

  • 我在雄猫上部署了一个泽西岛 2.5.1 应用程序。我在我的网络中添加了以下配置.xml: 它打印请求和响应头。但是,它没有在响应中打印请求/响应实体/主体。 我试着和不同的情妇玩,但没有运气,比如: 感谢您的回答。看起来我在上面粘贴了错误的配置。这是我在我的网络上有什么.xml: 它记录标题。但它不记录实体。这是我在日志中看到的: 我的Jersey应用程序部署在Tomcat 7_50服务器上。 如