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

使用RestTemplate调用GraphQL接口时出现400 Bad Request错误

SpringBoot中RestTemplate调用GraphQL API报400 Bad Request的解决方法

在SpringBoot中使用RestTemplate调用公开GraphQL API(https://countries.trevorblades.com/graphql)时,多次出现*HttpClientErrorException$BadRequest: 400 Bad Request*错误,以下是问题场景及解决方案:


问题场景1:Content-Type设为APPLICATION_GRAPHQL

代码实现

public class GetRespPayLoad {

    private final String url = "https://countries.trevorblades.com/graphql";

    public void getPayload(){

        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_GRAPHQL);

        String query = "{\n" +
                "  country(code: \"BR\") {\n" +
                "    name\n" +
                "    native\n" +
                "    capital\n" +
                "    emoji\n" +
                "    currency\n" +
                "    languages {\n" +
                "      code\n" +
                "      name\n" +
                "    }\n" +
                "  }";

        ResponseEntity<String> response = restTemplate.postForEntity(url, new HttpEntity<>(query, headers), String.class);

        System.out.println(response);
    }
}

错误信息

Caused by: org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: "POST body missing, invalid Content-Type, or JSON object has no keys."


问题场景2:Content-Type设为APPLICATION_JSON

代码实现

public class GetRespPayLoad {

    private final String url = "https://countries.trevorblades.com/graphql";

    public void getPayload(){

        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        String query = "query Query {\n" +
                "  country(code: \"BR\") {\n" +
                "    name\n" +
                "    native\n" +
                "    capital\n" +
                "    emoji\n" +
                "    currency\n" +
                "    languages {\n" +
                "      code\n" +
                "      name\n" +
                "    }\n" +
                "  }\n" +
                "}";

        ResponseEntity<String> response = restTemplate.postForEntity(url, new HttpEntity<>(query, headers), String.class);

        System.out.println(response);
    }
}

错误信息

Caused by: org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Request: "Error

Bad Request
"


解决方案

方案1:使用APPLICATION_JSON格式(推荐)

GraphQL的application/json请求要求体是包含query字段的JSON对象,而非直接传入查询字符串。可以通过Map构建请求体避免手动转义:

public class GetRespPayLoad {

    private final String url = "https://countries.trevorblades.com/graphql";

    public void getPayload(){
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("query", "query { country(code: \"BR\") { name native capital emoji currency languages { code name } } }");

        ResponseEntity<String> response = restTemplate.postForEntity(url, new HttpEntity<>(requestBody, headers), String.class);

        System.out.println(response.getBody());
    }
}

方案2:使用APPLICATION_GRAPHQL格式

RestTemplate默认未注册application/graphql的消息转换器,需手动添加后再发送请求:

public class GetRespPayLoad {

    private final String url = "https://countries.trevorblades.com/graphql";

    public void getPayload(){
        RestTemplate restTemplate = new RestTemplate();
        // 注册支持application/graphql的消息转换器
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter(MediaType.APPLICATION_GRAPHQL));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_GRAPHQL);

        String query = "{\n" +
                "  country(code: \"BR\") {\n" +
                "    name\n" +
                "    native\n" +
                "    capital\n" +
                "    emoji\n" +
                "    currency\n" +
                "    languages {\n" +
                "      code\n" +
                "      name\n" +
                "    }\n" +
                "  }\n" +
                "}";

        ResponseEntity<String> response = restTemplate.postForEntity(url, new HttpEntity<>(query, headers), String.class);

        System.out.println(response.getBody());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:24:33