Rest Assured发送带参带头POST请求时无法解析JSON文档问题
Rest Assured调用接口返回400且JSON解析失败异常排查
异常信息
使用Rest Assured执行POST请求、尝试从响应体提取tokenId字段时抛出如下异常:
io.restassured.path.json.exception.JsonPathException: Failed to parse the JSON document at io.restassured.path.json.JsonPath$ExceptionCatcher.invoke(JsonPath.java:1002) at io.restassured.path.json.JsonPath$4.doParseWith(JsonPath.java:967) at io.restassured.path.json.JsonPath$JsonParser.parseWith(JsonPath.java:1047) at io.restassured.path.json.JsonPath.get(JsonPath.java:202) at io.restassured.path.json.JsonPath.getString(JsonPath.java:352) at com.restassured.oauth.AuthenticateSetup.authenticateSetup(AuthenticateSetup.java:39) at com.restassured.runner.TestRunner.testNgBeforeSuite(TestRunner.java:31) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124) at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59) at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458) at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222) at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:401) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org.testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66) at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109) Caused by: groovy.json.JsonException: Lexing failed on line: 1, column: 1, while reading '<', no possible valid JSON value or punctuation could be recognized. at groovy.json.JsonLexer.nextToken(JsonLexer.java:86) at groovy.json.JsonLexer$nextToken.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130) at io.restassured.internal.path.json.ConfigurableJsonSlurper.parse(ConfigurableJsonSlurper.groovy:97) at io.restassured.internal.path.json.ConfigurableJsonSlurper$parse.callCurrent(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185) at io.restassured.internal.path.json.ConfigurableJsonSlurper.parseText(ConfigurableJsonSlurper.groovy:83) at io.restassured.path.json.JsonPath$4$1.method(JsonPath.java:965) at io.restassured.path.json.JsonPath$ExceptionCatcher.invoke(JsonPath.java:1000) ... 25 more
问题业务代码
public class AuthenticateSetup { public static Response response; public static String responseString; public static ReadPropertyFile urlProperties; public void authenticationSetup() throws JsonException { urlProperties = new ReadPropertyFile("./src/test/resources/Url.properties"); RestAssured.baseURI = urlProperties.getProperty("devAuthBaseUrl"); response = given() .config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("*/*", ContentType.JSON))) //.contentType(ContentType.ANY) .param("authIndexType", "service") .param("authIndexValue", "ldapService") .header("host", RestAssured.baseURI) .header("X-OpenAM-Username",urlProperties.getProperty("contactId")) .header("X-OpenAM-Password",urlProperties.getProperty("contactPwd")) .header("Accept-API-Version","resource=2.0,protocol=1.0") .when() .post(urlProperties.getProperty("devVGWAuthenticateUrl")) .then() // .assertThat() // .statusCode(200) .extract().response(); System.out.println("The response is " + response); String tokenId = response.jsonPath().getString("tokenId"); System.out.println("The token id is " + tokenId); } }
现存问题
- 调用
jsonPath()解析响应提取tokenId时抛出JSON解析失败异常,错误提示响应首字符为<,不属于合法JSON格式 - 开启
statusCode(200)断言时,接口返回400 Bad Request错误 - 完全相同的请求参数、请求头在Postman中可以正常调用并返回预期结果,最初添加encoderConfig配置是为了解决之前遇到的编码错误
根因与解决方案
两个异常属于同一根因:请求构造不符合接口要求,服务端返回了HTML格式的错误页(以<html>标签开头),因此既返回400状态码,又无法按JSON格式解析。按以下优先级排查修复:
- 修正参数传递方式
.param()方法仅用于传递URL查询参数或application/x-www-form-urlencoded格式的表单参数,对应OpenAM 2.0版本认证接口要求,authIndexType、authIndexValue参数需要放在JSON请求体中传递。原有代码用.param()传参会把参数拼接在URL后,后端无法识别合法请求体,直接返回400。
删除原有错误的encoderConfig配置,显式指定请求Content-Type为JSON,将参数放入请求体传递,同时添加Accept头告知服务端返回JSON格式响应:
// 构造JSON请求体,可根据项目依赖选用JSONObject、Map或实体类 HashMap<String, String> requestBody = new HashMap<>(); requestBody.put("authIndexType", "service"); requestBody.put("authIndexValue", "ldapService"); response = given() .contentType(ContentType.JSON) .accept(ContentType.JSON) .header("X-OpenAM-Username",urlProperties.getProperty("contactId")) .header("X-OpenAM-Password",urlProperties.getProperty("contactPwd")) .header("Accept-API-Version","resource=2.0,protocol=1.0") .body(requestBody) .when() .post(urlProperties.getProperty("devVGWAuthenticateUrl")) .then() .log().all() // 调试阶段开启全量日志,可直接查看实际发出的请求、返回的响应完整内容 .assertThat() .statusCode(200) .extract().response();
- 删除错误的Host头配置
手动设置的.header("host", RestAssured.baseURI)存在格式错误:Host头仅允许携带域名+端口,不能包含http:///https://协议前缀,格式非法的Host头会触发服务端域名校验失败返回400。Rest Assured会根据请求目标地址自动生成合法的Host头,无需手动配置。 - 校验请求URL正确性
核对配置文件中devAuthBaseUrl与devVGWAuthenticateUrl拼接后的完整地址,确认和Postman中调用的地址完全一致,排查是否存在多余斜杠、路径遗漏、环境地址配置错误的问题,地址错误会触发网关返回HTML格式的404/400错误页。
调试技巧:解析响应前先打印
response.getStatusCode()和response.asString(),只要响应内容首字符为<,即可确认返回的是HTML错误页,优先排查请求构造问题,无需在JSON解析逻辑上浪费时间。
内容的提问来源于stack exchange,提问作者wheelerlc64
相关产品推荐
相关产品推荐

