Spring REST 文档中的转义管道符号

Escape pipe symbol in Spring REST Docs

我需要记录一个 API 接受一个 JSON 表示 class:

public class Message {
    
    @NotNull(message = "Sender cannot be null")
    private String sender;
    
    @Pattern(regexp="HI|HELLO",message = "Message can be only 'HI' or 'HELLO'")
    private String content;
    
    // Constructor, Getters and Setters..
}

Spring Docs 自动生成以下代码段:

.Request fields:
|===
|Path|Type|Constraints|Description

|sender
|String
|Must not be null
|Sender of the message

|content
|String
|Must match the regular expression `HI|HELLO`
|Content of the message

|===

Asciidoctor 使用它在 pdf 中创建一个 table。但是,在 pdf 中,table 被破坏了(因为管道):

如何在正则表达式中转义管道?

我找到了这个 issue,但似乎与另一个项目有关。

这是生成文档 (JUnit5) 的测试 class:

@WebMvcTest(HomeController.class)
@AutoConfigureRestDocs(outputDir = "target/snippets")
public class HomeControllerTest {

    @Autowired
    private MockMvc mockMvc;
    
    @Test
    public void postMessageTest() throws Exception {
        ConstrainedFields constrainedFields = new ConstrainedFields(Message.class);
        
        this.mockMvc
                .perform(post("/message").content("{\"sender\":\"Marc\",\"content\":\"HI\"}")
                        .characterEncoding("utf-8")
                        .contentType(MediaType.APPLICATION_JSON))
                .andDo(print()).andExpect(status().isOk())
                .andDo(document("home-message", requestFields(
                        attributes(key("title").value("Request fields:")),
                        constrainedFields.withPath("sender").description("Sender of the message"),
                        constrainedFields.withPath("content").description("Content of the message")
                        )));
    }

    private static class ConstrainedFields {
        private final ConstraintDescriptions constraintDescriptions;
        
        ConstrainedFields(Class<?> input) {
            this.constraintDescriptions = new ConstraintDescriptions(input);
        }
        
        private FieldDescriptor withPath(String property) {
            return fieldWithPath(property).attributes(key("constraints").value(
                    // Let's assume there is only one constraint for each property
                    constraintDescriptions.descriptionsForProperty(property).get(0)));
        }
    }
}

重现问题的完整项目是 here

可能不是最好的解决方案,但是,经过一些研究,我发现一个简单的 \ 字符就足以转义 asciidoctor 文档中的竖线字符 (source) .我们的目标是在 .adoc 片段中得到这一行:

|Must match the regular expression `HI\|HELLO`

这是在您的代码中提取“约束描述”的方法:

private FieldDescriptor withPath(String property) {
    return fieldWithPath(property).attributes(key("constraints").value(
            // Let's assume there is only one constraint for each property
            constraintDescriptions.descriptionsForProperty(property).get(0)));
}

这里我们可以“完全控制”将写入 .adoc 的文本。例如,我们可以从 constraintDescriptions.descriptionsForProperty(property) 中获取约束描述,应用我们的转义,然后将转义的字符串传递给 .value():

private FieldDescriptor withPath(String property) {
    // Let's assume there is only one constraint for each property
    String desc = constraintDescriptions.descriptionsForProperty(property).get(0);
    desc = desc.replace("|", "\|");
    return fieldWithPath(property).attributes(key("constraints").value(desc));
}

这将在 .adoc 中生成转义行,并将在 .pdf 中正确呈现: