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

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格式解析。按以下优先级排查修复:

  1. 修正参数传递方式
    .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();
  1. 删除错误的Host头配置
    手动设置的.header("host", RestAssured.baseURI)存在格式错误:Host头仅允许携带域名+端口,不能包含http:///https://协议前缀,格式非法的Host头会触发服务端域名校验失败返回400。Rest Assured会根据请求目标地址自动生成合法的Host头,无需手动配置。
  2. 校验请求URL正确性
    核对配置文件中devAuthBaseUrl与devVGWAuthenticateUrl拼接后的完整地址,确认和Postman中调用的地址完全一致,排查是否存在多余斜杠、路径遗漏、环境地址配置错误的问题,地址错误会触发网关返回HTML格式的404/400错误页。

调试技巧:解析响应前先打印response.getStatusCode()和response.asString(),只要响应内容首字符为<,即可确认返回的是HTML错误页,优先排查请求构造问题,无需在JSON解析逻辑上浪费时间。


内容的提问来源于stack exchange,提问作者wheelerlc64

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:06:20