WireMock单元测试响应体编码异常问题求助
WireMock模拟HTTP请求响应体编码异常排查与解决
问题背景
单元测试中使用WireMock模拟POST请求返回,能正常获取200状态码和Cookie,但响应体乱码导致JSON解析失败。直接通过测试工具调用Stub端点编码正常,仅通过Feign业务客户端调用时出现问题。
相关代码片段
Stub配置代码
public static void setupMockExecutionResponse(WireMockServer mockService) throws IOException { mockService.stubFor(WireMock.post(WireMock.urlEqualTo("/reportExecutions")) .willReturn(WireMock.aResponse() .withStatus(HttpStatus.OK.value()) .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE+"; charset=utf-8") .withHeader("set-cookie", "JSESSIONID=1111111111111; SERVERID=jasper") .withBody( copyToString( JasperClientMock.class.getClassLoader().getResourceAsStream("payload/execution-response.json"), StandardCharsets.UTF_8)))); }
响应JSON文件(UTF-8编码)
{ "status":"ready", "totalPages":1, "requestId":"217f7dc9-47c4-4c44-bada-7e29b653887b", "reportURI":"/test/test/test/test/export_test", "exports":[{ "status":"ready", "outputResource":{"contentType":"application/pdf","fileName":"export_test.pdf","outputFinal":true,"outputTimestamp":0}, "id":"6ca0038f-94ff-4bd9-bdf4-6a35259fd05e" }] }
业务调用代码
feign.Response r = jasperFeignClient.executeReport(headerMap, requestBody); checkResponseStatut(r.status(), EXECUTION_STEP, documentJasperRequest.getUrlReport(), requestBody); getCookie(r, cookies); String execResponse = IOUtils.toString(r.body().asInputStream(), String.valueOf(StandardCharsets.UTF_8));
正常测试代码(直接调用Stub)
@Test public void testGetPDF(){ Response response = given().when().post("http://localhost:9561/reportExecutions"); String status = response.jsonPath().get("status"); System.out.println(status); assertEquals(status, "ready"); }
解决方法
1. 修正WireMock响应体传递方式
避免将文件内容转成字符串后设置body,直接传递字节数组跳过编码转换环节:
// 替换原withBody部分 .withBody(IOUtils.toByteArray( JasperClientMock.class.getClassLoader().getResourceAsStream("payload/execution-response.json")))
原因:withBody(String)会使用WireMock默认字符编码重新编码字符串,可能破坏原UTF-8内容,直接传递字节数组能保证原始编码不变。
2. 修复业务代码的字符集参数
IOUtils.toString支持直接传入Charset对象,无需转成字符串,避免潜在转换问题:
String execResponse = IOUtils.toString(r.body().asInputStream(), StandardCharsets.UTF_8);
3. 配置Feign客户端强制UTF-8解码
Feign默认可能未指定解码字符集,需显式配置:
方式1:通过Bean配置Decoder
@Bean public Decoder feignDecoder() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setCharset(StandardCharsets.UTF_8); return new JacksonDecoder(objectMapper); }
方式2:通过配置文件指定
feign.client.config.default.decoder.charset=UTF-8
4. 确认JSON文件编码
用文本编辑器(如Notepad++)打开JSON文件,确保保存为无BOM的UTF-8格式,带BOM的UTF-8可能导致部分解析器识别异常。
内容的提问来源于stack exchange,提问作者Erwan Le Tutour
相关产品推荐
相关产品推荐

