在Spring REST Docs中转义管道符号。

huangapple go评论82阅读模式
英文:

Escape pipe symbol in 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;
    
    // 构造函数,Getter和Setter..
}

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中,表格被打断了(因为有管道符号):

在Spring REST Docs中转义管道符号。

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

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

这是用于生成文档的测试类(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(
                    // 假设每个属性只有一个约束
                    constraintDescriptions.descriptionsForProperty(property).get(0)));
        }
    }
}

复现此问题的完整项目在这里

英文:

I need to document an API that accepts a JSON represented by this class:

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

Spring Docs autogenerates the following snippet:

.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

|===

Which is used by Asciidoctor to create a table in the pdf. However, in the pdf, the table is broken (because of the pipe):

在Spring REST Docs中转义管道符号。

How can I escape the pipe within the regular expression?

I found this issue, but seems to be related to another project.

This is the test class to generate the documentation (JUnit5):

@WebMvcTest(HomeController.class)
@AutoConfigureRestDocs(outputDir = &quot;target/snippets&quot;)
public class HomeControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void postMessageTest() throws Exception {
ConstrainedFields constrainedFields = new ConstrainedFields(Message.class);
this.mockMvc
.perform(post(&quot;/message&quot;).content(&quot;{\&quot;sender\&quot;:\&quot;Marc\&quot;,\&quot;content\&quot;:\&quot;HI\&quot;}&quot;)
.characterEncoding(&quot;utf-8&quot;)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isOk())
.andDo(document(&quot;home-message&quot;, requestFields(
attributes(key(&quot;title&quot;).value(&quot;Request fields:&quot;)),
constrainedFields.withPath(&quot;sender&quot;).description(&quot;Sender of the message&quot;),
constrainedFields.withPath(&quot;content&quot;).description(&quot;Content of the message&quot;)
)));
}
private static class ConstrainedFields {
private final ConstraintDescriptions constraintDescriptions;
ConstrainedFields(Class&lt;?&gt; input) {
this.constraintDescriptions = new ConstraintDescriptions(input);
}
private FieldDescriptor withPath(String property) {
return fieldWithPath(property).attributes(key(&quot;constraints&quot;).value(
// Let&#39;s assume there is only one constraint for each property
constraintDescriptions.descriptionsForProperty(property).get(0)));
}
}
}

The full project to reproduce the issue is here.

答案1

得分: 1

可能不是最好的解决方案,但经过一些研究,我发现一个简单的\字符足以在asciidoctor文档中转义管道符号(来源)。因此,我们的目标是在.adoc片段中获取这一行:

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

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

private FieldDescriptor withPath(String property) {
    return fieldWithPath(property).attributes(key("constraints").value(
            // 假设每个属性只有一个约束
            constraintDescriptions.descriptionsForProperty(property).get(0)));
}

在这里,我们对将在.adoc中编写的文本拥有“完全控制权”。例如,我们可以从constraintDescriptions.descriptionsForProperty(property)中获取约束描述,对其进行转义,然后将转义后的字符串传递给.value()

private FieldDescriptor withPath(String property) {
    // 假设每个属性只有一个约束
    String desc = constraintDescriptions.descriptionsForProperty(property).get(0);
    desc = desc.replace("|", "\\|");
    return fieldWithPath(property).attributes(key("constraints").value(desc));
}

这将在.adoc中生成已转义的行,并且在.pdf中将被正确渲染:

在Spring REST Docs中转义管道符号。

英文:

probably not the best solution, but, after doing little research, I found out that a simple \ character is enough to escape pipe character in asciidoctor documents (source). our goal then is to get this line in the .adoc snippet:

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

this is the method that extracts "constraints descriptions" in your code:

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

here we have "full control" over the text that will be written in the .adoc. we could for example take the constraint description from constraintDescriptions.descriptionsForProperty(property), apply our escaping and than pass the escaped string to .value():

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

this will produce the escaped line in the .adoc and will be correctly rendered in the .pdf:

在Spring REST Docs中转义管道符号。

huangapple
  • 本文由 发表于 2020年9月26日 16:24:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/64075493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定