gpt4 book ai didi

java - 使用 Spring REST Docs 记录分层 JSON 负载

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:08:05 26 4
gpt4 key购买 nike

我开始使用Spring REST Docs记录一个简单的 REST API。我有一个具有某种层次结构的有效负载,例如像这样(有员工的公司)。

{
"companyName": "FooBar",
"employee":
[
{
"name": "Lorem",
"age": "42"
},

{
"name": "Ipsum",
"age": "24"
}
]
}

我想将公司对象(员工的姓名和数组)和员工对象(员工姓名和年龄)的文档分开。

像解释的那样使用 org.springframework.restdocs.payload.PayloadDocumentation.responseFields here迫使我记录所有字段,但如果我只想记录 employee 字段 - 我该如何实现?

我可以在没有员工详细信息的情况下记录公司,因为如果一个字段是文档,则后代也被视为已记录。但是我无法单独记录员工结构,而且在没有公司根对象的情况下,我没有专门用于此结构的有效负载。

最佳答案

受此问题的启发,我实现了一项增强功能,使原始答案(见下文)过时。

如果您使用 1.0.0.BUILD-SNAPSHOT(可从 https://repo.spring.io/libs-snapshot 获得),您现在可以将一个字段标记为已忽略。已记录忽略的字段数,但实际上并未出现在文档中。

鉴于您想要分离文档,进行两次文档调用是有意义的。在第一个文件中,您可以记录公司名称和员工数组。在第二个文件中,您记录了员工数组并将公司名称标记为已忽略。

你的测试看起来像这样:

mockMvc.perform(get("/company/5").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("company",
responseFields(
fieldWithPath("companyName").description(
"The name of the company"),
fieldWithPath("employee").description(
"An array of the company's employees"))))
.andDo(document("employee",
responseFields(
fieldWithPath("companyName").ignored(),
fieldWithPath("employee[].name").description(
"The name of the employee"),
fieldWithPath("employee[].age").description(
"The age of the employee"))));

您最终会得到两个片段目录,一个名为 company,另一个名为 employee。然后,您可以使用每个中的 response-fields.adoc 片段。

原始答案

当您记录请求或响应时,没有明确支持忽略字段,但我认为您可以通过使用预处理器删除您不想记录的字段来实现您想要的。

鉴于您想要分离文档,进行两次 document 调用是有意义的。在第一个文件中,您可以记录公司名称和员工数组。第二,您需要预处理删除公司的请求,然后记录员工数组。

你的测试看起来像这样:

mockMvc.perform(get("/company/5").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("company",
responseFields(
fieldWithPath("companyName").description(
"The name of the company"),
fieldWithPath("employee").description(
"An array of the company's employees"))))
.andDo(document("employee",
preprocessResponse(removeCompany()),
responseFields(
fieldWithPath("employee[].name").description(
"The name of the employee"),
fieldWithPath("employee[].age").description(
"The age of the employee"))));

请注意在第二个 document 调用中使用了 preprocessResponseremoveCompany 返回一个预处理器,它使用自定义 ContentModifier 从响应中删除公司名称:

private OperationPreprocessor removeCompany() {
return new ContentModifyingOperationPreprocessor(new ContentModifier() {

@Override
public byte[] modifyContent(byte[] originalContent, MediaType contentType) {
ObjectMapper objectMapper = new ObjectMapper();
try {
Map<?, ?> map = objectMapper.readValue(originalContent, Map.class);
map.remove("companyName");
return objectMapper.writeValueAsBytes(map);
}
catch (IOException ex) {
return originalContent;
}
}

});
}

您最终会得到两个片段目录,一个名为 company,另一个名为 employee。然后,您可以使用每个中的 response-fields.adoc 片段。

虽然上述方法可行,但比需要的要难。我打开了an issue这样就不再需要修改响应内容的预处理。

关于java - 使用 Spring REST Docs 记录分层 JSON 负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32865427/

26 4 0
文章推荐: java - 类型参数 G 隐藏了类型 G
文章推荐: android - 如何通过Canvas DrawBitmap绘制位图的一部分
文章推荐: java - 如何在 Java 中将 List 转换为 List