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

NexarAPI中GraphQL带参数查询报错及RestTemplate调用问题求助

Nexar API GraphQL查询异常排查与解决

问题现象

  • 发送无参数的基础GraphQL查询,设置Content-Type: application/json时可正常获取数据:
    {  "query": "query Categories { supCategories { id name path }}" }
    
  • 发送带workspaceUrl参数的查询时,抛出语法错误:
    { "query": "query design2_Library { desLibrary (workspaceUrl: \"test\") { components { nodes { id name manufacturerParts { partNumber companyName } details { parameters { name value } } } } } }" }
    
    错误信息:

    <200,{"errors":[{"message":"Expected a String-token, but found a Name-token.","locations":[{"line":1,"column":64}],"extensions":{"code":"HC0011"}}]},[Date:"Fri, 21 Jun 2024 11:16:40 GMT", Content-Type:"application/json; charset=utf-8", Transfer-Encoding:"chunked", Server:"Kestrel", Cache-Control:"proxy-revalidate", X-SYMC-Transaction-UUID:"8b74d844d6cf25c1-000000000b3ff64b-0000000066756118", Connection:"keep-alive"]>

  • 尝试将Content-Type改为graphql时,返回404错误。

相关Java RestTemplate代码

public String getComponent(String query) {
    logger.info("getComponent {Query:" + query + "}");
    try {
        Context initContext = new InitialContext();
        Map token = generateOAuthAcessToken(initContext, "QA");
        String url = nexarEndPoint;
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam("partNo", query);

        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(
            Arrays.asList(new MediaType[] { MediaType.valueOf("application/graphql-response+json") }));
        headers.setContentType(MediaType.valueOf("application/graphql-response+json"));
        // headers.setContentType(customMediaType);
        headers.add("Authorization", "Bearer " + token.get("access_token"));

        String alternateQuery = "{\"query\":\"query design2_Library { desLibrary (workspaceUrl: \\\\<altium workspace url\\\\\") { components { nodes { id name manufacturerParts { partNumber companyName } details { parameters { name value } } } } } }\",\"variables\":{}}";
        query = "{  \"query\": \"query Categories { supCategories { id name path }}\"}";
        String graphqlQuery = "{ \"query\": \"query design2_Library { desLibrary (workspaceUrl: \"test\") { components { nodes { id name manufacturerParts { partNumber companyName } details { parameters { name value } } } } } }\" }";
        // String graphqlQuery1 = "{ \"query\": \"query design2_Library { desLibrary

        System.setProperty("https.protocols", "TLSv1.2");
        HttpEntity<String> entity = new HttpEntity<String>(query.toString(), headers);
        RestTemplate template = new RestTemplate();
        ResponseEntity<String> response = template.exchange(builder.toUriString(), HttpMethod.POST, entity, String.class);
        String result = response.getBody();
        JSONArray resultArr = new JSONObject(result).getJSONObject("data").getJSONObject("desLibrary")                  .getJSONObject("components").getJSONArray("nodes");
        return resultArr.toString();
    } catch (Exception ex) {
        logger.error("Search value " + query + "\n" + ex.getMessage());
        return "Error : " + ex.getMessage();
    }
}

解决方案

1. 修复查询字符串转义问题

报错核心是JSON嵌套双引号未正确转义:workspaceUrl: "test"里的双引号会被JSON解析器误判为外层JSON的结束符。Java中需要用\\转义嵌套双引号,修正后的查询字符串:

String graphqlQuery = "{ \"query\": \"query design2_Library { desLibrary (workspaceUrl: \\\"test\\\") { components { nodes { id name manufacturerParts { partNumber companyName } details { parameters { name value } } } } } }\" }";

2. 规范Content-Type设置

保持Content-Type: application/json即可,Nexar API大概率不支持graphql类型的POST端点。同时统一Accept头为标准格式:

headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);

3. 用JSON库构造请求体(推荐)

手动拼接JSON容易出错,使用Jackson/Gson等库序列化请求体,彻底避免转义问题:

// 构造请求体Map
Map<String, Object> requestBody = new HashMap<>();
String graphqlQueryStr = "query design2_Library { desLibrary (workspaceUrl: \"test\") { components { nodes { id name manufacturerParts { partNumber companyName } details { parameters { name value } } } } } }";
requestBody.put("query", graphqlQueryStr);

// 序列化为JSON字符串
ObjectMapper objectMapper = new ObjectMapper();
String requestJson = objectMapper.writeValueAsString(requestBody);

// 构造请求实体
HttpEntity<String> entity = new HttpEntity<>(requestJson, headers);

4. 移除不必要的URL参数

Nexar API的GraphQL参数应放在请求体中,而非URL参数,移除代码中的partNo查询参数:

// 原代码:UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url).queryParam("partNo", query);
// 修改为:
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);

5. 增加响应空值判断

原代码链式调用getJSONObject/getJSONArray容易因数据为空抛出异常,添加空值检查:

JSONObject resultObj = new JSONObject(result);
JSONArray resultArr = new JSONArray();
if (resultObj.has("data") && !resultObj.isNull("data")) {
    JSONObject dataObj = resultObj.getJSONObject("data");
    if (dataObj.has("desLibrary") && !dataObj.isNull("desLibrary")) {
        JSONObject desLibraryObj = dataObj.getJSONObject("desLibrary");
        if (desLibraryObj.has("components") && !desLibraryObj.isNull("components")) {
            JSONObject componentsObj = desLibraryObj.getJSONObject("components");
            if (componentsObj.has("nodes") && !componentsObj.isNull("nodes")) {
                resultArr = componentsObj.getJSONArray("nodes");
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:55:58