WireMock POST请求匹配失败求助:GET正常POST无法拦截请求
WireMock POST请求匹配失败排查方案
问题情况
已成功用WireMock完成GET请求测试,但POST请求始终无法被识别拦截,URL看似匹配却返回404,想确认POST请求是否需要匹配URL之外的内容。
WireMock版本:com.github.tomakehurst:wiremock:2.5.1
Stub代码
stubFor(post(urlPathEqualTo("/data/")) .willReturn(aResponse().withHeader("Content-Type", "application/json") .withBody(dataContent.toString())));
WireMock日志
[2024-02-18 14:40:44.819] ERROR [WireMock error]: Request was not matched: { "url" : "/data/", "absoluteUrl" : "http://localhost:4999/data/", "method" : "POST", "clientIp" : "127.0.0.1", "headers" : { "Authorization" : "Bearer null", "Accept" : "text/plain, application/xml, text/xml, application/json, application/*+xml, application/*+json, */*", "Connection" : "keep-alive", "User-Agent" : "Apache-HttpClient/4.5.13 (Java/1.8.0_121)", "Host" : "localhost:4999", "Accept-Encoding" : "gzip,deflate", "Content-Length" : "89", "Content-Type" : "application/json" }, "cookies" : { }, "browserProxyRequest" : false, "loggedDate" : 1708285244644, "bodyAsBase64" : "oauth token", "body" : "{\"query\":\"NIB_POSITION\",\"datasource_name\":\"webservice\",\"params\":{\"@ASOFDATE\":\"20221031\"}}", "loggedDateString" : "2024-02-18T19:40:44Z" } [2024-02-18 14:40:45.048] ERROR [WireMock error]: Request was not matched: { "url" : "/data/", "absoluteUrl" : "http://localhost:4999/data/", "method" : "POST", "clientIp" : "127.0.0.1", "headers" : { "Authorization" : "Bearer null", "Accept" : "text/plain, application/xml, text/xml, application/json, application/*+xml, application/*+json, */*", "Connection" : "keep-alive", "User-Agent" : "Apache-HttpClient/4.5.13 (Java/1.8.0_121)", "Host" : "localhost:4999", "Accept-Encoding" : "gzip,deflate", "Content-Length" : "89", "Content-Type" : "application/json" }, "cookies" : { }, "browserProxyRequest" : false, "loggedDate" : 1708285245022, "bodyAsBase64" : "oauth token", "body" : "{\"query\":\"NIB_POSITION\",\"datasource_name\":\"webservice\",\"params\":{\"@ASOFDATE\":\"20220930\"}}", "loggedDateString" : "2024-02-18T19:40:45Z" }
发起POST请求的代码
String token = RopcClientUtils.getV2RopcClient().getJwtToken(restTemplate); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.add("Authorization", "Bearer " + token); //url for webservice URL mwsUrl = new URL(getServer(CONNECTION) + "/data/"); //setup requested payload String payload = this.toJson(); HttpEntity<?> requestEntry = new HttpEntity<>(payload, headers); ResponseEntity<String> res = restTemplate.postForEntity(mwsUrl.toURI(), requestEntry, String.class); if (!HttpStatus.OK.equals(res.getStatusCode())) { throw new Exception("HTTP status: " + res.getStatusCode()); } result = JsonParser.parseString(Objects.requireNonNull(res.getBody(), "Received Empty results from WebService.")); } catch (Exception e) { LOGGER.warning("Error while requesting webservice" + e); } // mwsUrl实际值: http://localhost:4999//data/
抛出的异常
org.springframework.web.client.HttpClientErrorException$NotFound: 404 Not Found: "<html><EOL><head><EOL><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/><EOL><title>Error 404 Not Found</title><EOL></head><EOL><body><h2>HTTP ERROR 404</h2><EOL><p>Problem accessing /data/. Reason:<EOL><pre> Not Found</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.12.v20180830</a><hr/><EOL><EOL></body><EOL></html><EOL>"
排查与解决步骤
修正URL中的双斜杠问题
从请求代码可见,mwsUrl实际值为http://localhost:4999//data/,存在双斜杠冗余。尽管Jetty可能自动归一化路径,但WireMock路径匹配逻辑严格,建议调整URL拼接逻辑:// 确保服务器地址末尾无斜杠后再拼接路径 String serverUrl = getServer(CONNECTION); if (serverUrl.endsWith("/")) { serverUrl = serverUrl.substring(0, serverUrl.length() - 1); } URL mwsUrl = new URL(serverUrl + "/data/");调整Stub匹配规则
老版本WireMock(2.5.1)可能存在兼容性问题,可尝试补充匹配条件或更换匹配方式:- 添加Content-Type头匹配:
stubFor(post(urlPathEqualTo("/data/")) .withHeader("Content-Type", equalTo("application/json")) .willReturn(aResponse().withHeader("Content-Type", "application/json") .withBody(dataContent.toString()))); - 改用
urlEqualTo代替urlPathEqualTo(适用于无查询参数的场景):stubFor(post(urlEqualTo("/data/")) .willReturn(aResponse().withHeader("Content-Type", "application/json") .withBody(dataContent.toString())));
- 添加Content-Type头匹配:
确认Stub注册时机
保证Stub是在WireMock服务器启动后注册,且使用同一实例调用stubFor,提前注册的Stub不会生效。升级WireMock版本(可选)
2.5.1版本较老旧,存在已知兼容性问题,建议升级至2.35.0及以上的稳定版本,避免老版本BUG影响匹配逻辑。
内容的提问来源于stack exchange,提问作者Krish Srinivasan
相关产品推荐
相关产品推荐

