Spring Boot 2.5.0 - REST 控制器,MockMvc 不是 UTF-8
Posted
技术标签:
【中文标题】Spring Boot 2.5.0 - REST 控制器,MockMvc 不是 UTF-8【英文标题】:Spring Boot 2.5.0 - REST controller, MockMvc not UTF-8 【发布时间】:2021-08-13 17:52:20 【问题描述】:在我的 REST 控制器中,我使用
@PostMapping
、@GetMapping
等,没有任何其他规范。
因此默认值必须是JSON
,例如@GetMapping
。也没有指定字符编码,我假设它必须是UTF-8
,我在文档中找不到默认字符编码。
但是在我的测试中我使用MockMvc
。
当我发出POST
请求时,它看起来像这样:
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 的控制台中,某些字符(例如德语 'ü'
)未正确打印。它看起来像(见正文):
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 response
是characterEncoding ISO-8859-1
? ISO-8859-1
来自哪里,这一套在哪里?可以改成UTF-8
吗?
当我改为尝试时:
String contentAsString = response.getContentAsString(StandardCharsets.ISO_8859_1);
我没有得到德语 'ü'
,字符串值是 "Tür"
。虽然在ISO_8859_1
中根据https://en.wikipedia.org/wiki/ISO/IEC_8859-1 字符'ü'
在代码页布局表中。
【问题讨论】:
【参考方案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
【讨论】:
以上是关于Spring Boot 2.5.0 - REST 控制器,MockMvc 不是 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 2.5.0、Spring Cloud 2020.0.2 和 Hibernate 5.4.31 - H2 数据库多行插入失败
列出所有已部署的 REST 端点(spring-boot、tomcat)
初入spring boot(八 )Spring Data REST