【问题标题】:Graphql bad request due escaped qoutes using spring boot RestTemplate由于使用 Spring Boot RestTemplate 转义了 qoutes 导致的 Graphql 错误请求
【发布时间】:2021-07-26 23:50:53
【问题描述】:

使用 postman 一切都是 fine 原始 JSON 内容类型。

{"query":"{getX(filter: \"X\", filter2: \"Y\") {data1, data2, data3} }

在 java client 中调用时,我得到 400 错误

String body = "{\"query\":\"{getX(filter: \\\"X\\\", filter2: \\\"Y\\\") {data1, data2, data3}}\"}"; 
// simply copied from postman to Intellij and it did some escaping for me
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity httpEntity = new HttpEntity<>(body, headers);
ResponseEntity<List<SomeObject>> response = restTemplate.exchange(uri, POST, httpEntity, new ParameterizedTypeReference<List<SomeObject>>(){});

服务器端我可以看到我收到了错误:

JSON parse error: Cannot construct instance of 'java.util.LinkedHashMap': no String-argument constructor/factory method to deserialize from String value ....
//Looks like server thinks I passed one big string
... payload="{\"query\":\"{getX(filter: \\\"X\\\", filter2: \\\"Y\\\") {data1, data2, data3}}\"}" ...

但是在 服务器端,当我从 postman 调用时,我得到了这个 payload log,它工作得很好

... payload={"query":"{getX(filter: \"X\", filter2: \"Y\") {data1, data2, data3}}"} ...

显然,我可以看到,当我从 java 有效负载调用时,数据包裹在 qoutes 中,并且每个 qoute 都在其中转义,同时来自邮递员的有效负载没有包裹在 qoutes 下,除了过滤器之外没有任何东西被转义。使用 restTemplate,我到底能做什么?

【问题讨论】:

    标签: java spring-boot graphql graphql-java


    【解决方案1】:

    我强烈建议使用变量来传递查询参数,如 GraphQL docs 中所示,并且还将推荐 insomnia 作为 GraphQL 查询的客户端,因为它支持具有良好 ui 表示的 GraphQL,可能下面将是您的请求带变量

    {
       "query":"query($filter_1: string, $filter_2 : string){getX(filter: $filter_1, filter2: $filter_2) {data1, data2, data3} }",
       "variables" : {"filter_1":"X", "filter_2": "Y"}
    }
    

    您必须在请求中传递所有上述有效负载广告 POST 正文

    【讨论】:

    • 老实说,我怀疑这是否能解决我目前遇到的问题。还没有尝试过,但我想我会得到完全相同的结果,只是变量也会被包含在引号内。如您所见,以前整个 json 请求看起来像被包裹在一个大字符串中
    • 变量是JSON所以你不需要ant引号来编码,我通常用这种方式实现GraphQL调用,附加的insomnai链接有很好的例子
    【解决方案2】:

    我找到了解决方案,基本上我所需要的只是将“查询”作为键放在地图中,否则放在值中。在这种情况下,body 不会被奇怪地包裹在 qoutes 中。

    Map<String, String> body = of("query", "{getX(filter: \"X\", filter2: \"Y\") {data1, data2, data3}}");
    HttpEntity httpEntity = new HttpEntity<>(body, headers);
    //and pass it to restTemplate...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-28
      • 2019-03-20
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2022-11-26
      • 2019-01-21
      • 2018-01-12
      相关资源
      最近更新 更多