首页 > 解决方案 > Spring REST Docs 中的转义管道符号

问题描述

我需要记录一个接受由此类表示的 JSON 的 API:

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 中创建一个表。但是,在 pdf 中,表格被破坏了(因为管道):

在此处输入图像描述

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

我发现了这个问题,但似乎与另一个项目有关。

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

@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)));
        }
    }
}

重现该问题的完整项目在这里

标签: javaspringspringdoc

解决方案


可能不是最好的解决方案,但是,在做了一些研究之后,我发现一个简单的\字符就足以在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

pdf


推荐阅读