Rest-Assured执行带路径参数的Get请求返回404错误排查
解决Rest Assured + TestNG GET请求404(Postman正常)的问题
我帮你分析下这个问题:你遇到的404错误,核心原因几乎可以确定是URL中的特殊字符没有被正确编码。Postman会自动对URL里的特殊字符(比如冒号:这类)做URL编码,但Rest Assured默认不会自动处理路径里的这类特殊字符,导致实际发送的请求路径和Postman的不一致,服务器匹配不到资源,就返回了404。
先把你的代码和错误日志格式化出来,方便查看:
你的测试代码
@Test public void listOfStepsTest() { try { RestAssured.given() .header("Access-Key", "a06669527b7bUCCzd4vx4JbYbKYLdV8rqr4DG-ejTnY9J_4_936QrnHcoeJtCsFhQGkNLJeb2wwu") .when() .get("http://xyz:8080/rest/runtime/XYZ111:XYZProject1:1.0-SNAPSHOT/process/XYZProject1.TaskExample") .then() .assertThat().statusCode(200); } catch (Exception e) { e.printStackTrace(); } }
关键错误日志
FAILED: listOfStepsTest java.lang.AssertionError: 1 expectation failed. Expected status code <200> but was <404>. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ...(中间堆栈省略) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
几种可行的解决方案
1. 用Rest Assured的路径参数语法(最推荐)
Rest Assured支持路径参数占位符,会自动帮你编码参数里的特殊字符,代码也更整洁易维护:
@Test public void listOfStepsTest() { try { RestAssured.given() .header("Access-Key", "a06669527b7bUCCzd4vx4JbYbKYLdV8rqr4DG-ejTnY9J_4_936QrnHcoeJtCsFhQGkNLJeb2wwu") // 定义路径参数,把带特殊字符的部分抽出来 .pathParam("processIdentifier", "XYZ111:XYZProject1:1.0-SNAPSHOT") .when() // 用{占位符}替换路径里的对应部分 .get("http://xyz:8080/rest/runtime/{processIdentifier}/process/XYZProject1.TaskExample") .then() .assertThat().statusCode(200); } catch (Exception e) { e.printStackTrace(); } }
这种方式下,Rest Assured会自动把冒号:编码成%3A,和Postman发送的请求路径一致,服务器就能正确匹配到资源了。
2. 手动编码特殊路径片段
如果不想用路径参数,也可以用Java的URLEncoder手动编码带特殊字符的部分:
@Test public void listOfStepsTest() { try { // 对带特殊字符的路径片段进行UTF-8编码 String encodedProcessId = URLEncoder.encode("XYZ111:XYZProject1:1.0-SNAPSHOT", "UTF-8"); // 拼接成完整URL String fullUrl = "http://xyz:8080/rest/runtime/" + encodedProcessId + "/process/XYZProject1.TaskExample"; RestAssured.given() .header("Access-Key", "a06669527b7bUCCzd4vx4JbYbKYLdV8rqr4DG-ejTnY9J_4_936QrnHcoeJtCsFhQGkNLJeb2wwu") .when() .get(fullUrl) .then() .assertThat().statusCode(200); } catch (Exception e) { e.printStackTrace(); } }
注意:URLEncoder只会编码非URL安全的字符,像连字符-、点.这类本来就是安全的,不会被编码,这和Postman的处理逻辑一致。
3. 打印请求日志验证实际URL
如果还是不确定问题出在哪,可以开启Rest Assured的日志打印,看看实际发送的URL和Postman里的是否一致:
@Test public void listOfStepsTest() { try { RestAssured.given() .header("Access-Key", "a06669527b7bUCCzd4vx4JbYbKYLdV8rqr4DG-ejTnY9J_4_936QrnHcoeJtCsFhQGkNLJeb2wwu") // 打印所有请求细节,包括最终生成的URL .log().all() .when() .get("http://xyz:8080/rest/runtime/XYZ111:XYZProject1:1.0-SNAPSHOT/process/XYZProject1.TaskExample") .then() // 打印响应细节,方便排查 .log().all() .assertThat().statusCode(200); } catch (Exception e) { e.printStackTrace(); } }
对比日志里的URL和Postman的请求URL,就能明确是不是编码导致的路径不匹配了。
总结
最推荐第一种路径参数的方式,既不用自己处理编码,代码可读性和维护性也更好。本质上就是要确保URL中的特殊字符被正确编码,让服务器能识别到对应的资源路径。
内容的提问来源于stack exchange,提问作者Saagar
相关产品推荐
相关产品推荐

