我使用Swagger设置REST Api服务。为此,我使用了以下版本:
swagger(YAML) - 文件版本2.0
swagger codegen cli version v2.3.0
springfox版本2.5.0
API服务的任务是响应我们存储在数据库中的数据及其关系。 但是,我们的数据中存在循环关系。这意味着每个对象a可以与对象b具有关系,对象b可以与对象a具有向后关系。
现在使用Swagger,这将生成无穷无尽的长JSON,从而导致错误。 代码如下所示:
public class Service extends DataObject {
@SerializedName("provides")
private List<Utility> provides;
/**
* Get provides
*
* @return provides
**/
@ApiModelProperty(required = true, value = "")
public List<Utility> getProvides() {
return provides;
}
}
public class Utility extends DataObject {
@SerializedName("providedBy")
private List<Service> providedBy;
/**
* Get providedBy
*
* @return providedBy
**/
@ApiModelProperty(required = true, value = "")
public List<Service> getProvidedBy() {
return providedBy;
}
}
然后在回复中:
@Override
public ResponseEntity<List<Service>> servicesGet(
@Min(0) @ApiParam(value = "The number of layers of relations the object is enriched by. Lower numbers typically increase performance.", defaultValue = "0") @Valid @RequestParam(value = "layersOfRelations", required = false, defaultValue = "0") final Integer layersOfRelations) {
String accept = this.request.getHeader("Accept");
List<Service> services = Util.getServices();
return new ResponseEntity<List<Service>>(services, HttpStatus.OK);
}
我的问题是,在哪里以及如何更改方法servicesGet()中为返回自动生成的输出?
我不想将整个对象b转换为JSON,而只将其转换为标题,这样就不会有无限的递归。
答案 0 :(得分:0)
因此经过一些研究后我发现,那个招摇使用Jackson将对象转换为JSON(即使生成的代码中包含的@SerializedName参数来自gson库,至少在我的情况下如此)。
这意味着在这种情况下,我可以简单地使用杰克逊提供的自定义技术,它就像一个魅力。 我只需编写自定义Jackson适配器注释:
@SerializedName("provides")
@JsonSerialize(using = DataObjectAdapter.class)
private List<Utility> provides;
并且适配器看起来像这样:
public static class DataObjectAdapter extends JsonSerializer<List<Utility>> {
@Override
public void serialize(final List<Utility> arg0, final JsonGenerator arg1, final SerializerProvider arg2)
throws IOException {
arg1.writeStartArray();
for (Utility object : arg0) {
arg1.writeStartObject();
arg1.writeStringField("id", object.getId());
arg1.writeStringField("title", object.getTitle());
arg1.writeStringField("description", object.getDescription());
arg1.writeEndObject();
}
arg1.writeEndArray();
}
}
所以现在不是将整个对象写入JSON(因此递归地将所有子对象添加到其中),他只会将我在适配器中描述的信息写入JSON。
类似地,我在JSON中读出ID并将其映射到我的数据的反序列化器看起来像这样
public static class ServiceDeserializer extends StdDeserializer<Service> {
public ServiceDeserializer() {
super(Service.class);
}
@Override
public Service deserialize(final JsonParser jp, final DeserializationContext ctxt)
throws IOException, JsonProcessingException {
List<Utility> objects = Util.getUtilities();
JsonNode node = jp.getCodec().readTree(jp);
String id = node.get("id").asText();
String title = node.get("title").asText();
String description = node.get("description").asText();
Service service = new Service(id, title, description);
for (JsonNode utility : node.get("provides")) {
String checkId = utility.get("id").asText();
for (DataObject object : objects) {
if (object.getId().equals(checkId)) {
service.addUtility(object);
break;
}
}
}
return service;
}
}