You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:52:11