Spring Boot 2.5.0 - REST控制器,MockMvc不支持UTF-8

4

在我的REST控制器中,我使用@PostMapping@GetMapping等注解而没有任何其他规定。

因此,默认情况下应该是JSON,例如对于@GetMapping。另外,没有指定字符编码,我认为它必须是UTF-8,我在文档中找不到默认字符编码。

然而,在我的测试中,我使用MockMvcPOST请求如下所示:

public static MvcResult performPost(MockMvc mockMvc, String endpoint, String payload, ResultMatcher status) throws Exception {
    MvcResult mvcResult = mockMvc.perform(
        post(endpoint)
            .content(payload)
            .contentType(MediaType.APPLICATION_JSON_VALUE))
        .andDo(print())
        .andExpect(status)
        .andReturn();

    return mvcResult;
}

问题:
.andDo(print()) 部分似乎没有使用 UTF-8。如何解决?一些像德语中的 'ü' 这样的字符在我的 NetBeans IDE 控制台中打印不正确。它看起来像 (见 Body):

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = application/json
             Body = {"Tür"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

问题:
当我的方法返回MvcResult时,我可以做什么:

MockHttpServletResponse response = mvcResult.getResponse(); 
ObjectMapper objectMapper = new ObjectMapper();
    
String contentAsString = response.getContentAsString(StandardCharsets.UTF_8);

我发现,我必须使用StandardCharset.UTF_8才能获得正确的字符,比如'ü'

但是,为什么在MockHttpServletResponse响应中,characterEncoding ISO-8859-1ISO-8859-1从何而来,它在哪里设置?能否将其更改为UTF-8

当我尝试使用以下代码:

String contentAsString = response.getContentAsString(StandardCharsets.ISO_8859_1);

我不理解德语中的 'ü',字符串的值为 "Tür"。尽管根据https://en.wikipedia.org/wiki/ISO/IEC_8859-1上的 Code page layout table,在ISO_8859_1 中字符 'ü' 是存在的。

2个回答

1

是的,这绝对很尴尬。

类:repository\org\springframework\spring-test\5.3.7\spring-test-5.3.7.jar!\org\springframework\test\web\servlet\result\MockMvcResultHandlers.class

方法:

public static ResultHandler print() {
    return print(System.out);
}

方法:

public static ResultHandler print(OutputStream stream) {
    return new PrintWriterPrintingResultHandler(new PrintWriter(stream, true));
}

构造函数:


public PrintWriter(OutputStream out, boolean autoFlush) {
    this(out, autoFlush, Charset.defaultCharset());
}

据我所知,罪魁祸首是 Charset.defaultCharset(),应该改为 UTF-8。

0

这个相关问题的答案展示了如何为所有测试设置默认编码(实际上文档没有说明默认值是什么)。

如果你不想依赖于(另一个)在测试之外设置的配置项,我相信在请求中设置编码将自动使 MockMvc 做正确的事情。我们在测试中使用这种方法,其中 JSON 负载带有重音字符。

 MvcResult mvcResult = mockMvc.perform(
    post(endpoint)
        .content(payload)
        .contentType(MediaType.APPLICATION_JSON_VALUE)
        .characterEncoding("utf-8"))
    .andDo(print())
    .andExpect(status)
    .andReturn();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接