加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用Spring REST Docs记录分层JSON有效负载

发布时间:2020-12-15 04:30:07 所属栏目:Java 来源:网络整理
导读:我开始使用 Spring REST Docs来记录一个简单的REST API.我有一个有一些分层结构的有效负载,例如像这样(有员工的公司). { "companyName": "FooBar","employee": [ { "name": "Lorem","age": "42" },{ "name": "Ipsum","age": "24" } ]} 我想分离公司对象(员工
我开始使用 Spring REST Docs来记录一个简单的REST API.我有一个有一些分层结构的有效负载,例如像这样(有员工的公司).

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

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

使用像解释here这样的org.springframework.restdocs.payload.PayloadDocumentation.responseFields迫使我记录所有字段,但是如果我只想记录员工字段 – 我该如何实现这一点?

在没有员工详细信息的情况下记录公司没有问题,因为如果字段是文档,则后代也被视为已记录.但我无法单独记录员工结构,如果没有公司根对象,我没有专门的有效负载.

解决方法

受这个问题的启发,我实施了一项增强功能,使原来的答案(见下文)过时了.

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

鉴于您想要分离文档,有两个文档调用是有道理的.首先,您可以记录公司名称和员工阵列.在第二个中,您记录了employees数组并将公司名称标记为已忽略.

您的测试看起来像这样:

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"))));

您将最终得到两个片段目录,一个名为公司,另一个名为员工.然后,您可以使用每个的response-fields.adoc片段.

原始答案

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

鉴于您想要分离文档,您可以记录公司名称和员工阵列.在第二步中,您需要预处理请求以删除公司,然后记录employees数组.

您的测试看起来像这样:

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

请注意在第二个文档调用中使用preprocessResponse. removeCompany返回一个预处理器,它使用自定义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;
            }
        }

    });
}

您将最终得到两个片段目录,您可以使用每个的response-fields.adoc片段.

虽然上述方法有效,但它比它需要的更难.我已经打开了an issue,因此不再需要修改响应内容的预处理.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读