如何从java访问github graphql API而不在java中运行curl命令

Posted

技术标签:

【中文标题】如何从java访问github graphql API而不在java中运行curl命令【英文标题】:how to access the github graphql API from java without running curl commands inside java 【发布时间】:2017-06-23 03:51:55 【问题描述】:

请原谅我的长问题,因为我是graphql 的初学者。我需要访问github graphql API 以获取某个文件的责任详情,因为到目前为止github API version 3 中没有责任REST API。我可以获得以下graphql 查询的输出,该查询在here 中运行

  query 
  repository(owner: "wso2-extensions", name: "identity-inbound-auth-oauth") 
    object(expression: "83253ce50f189db30c54f13afa5d99021e2d7ece") 
      ... on Commit 
        blame(path: "components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java") 
          ranges 
            startingLine
            endingLine
            age
            commit 
              message
              url
              history(first: 2) 
                edges 
                  node 
                    message
                    url
                  
                
              
              author 
                name
                email
              
            
          
        
      
    
  

在终端中运行以下curl 命令

curl -i -H "Authorization: bearer myGitHubToken" -X POST -d '"query": "query  repository(owner: \"wso2-extensions\", name: \"identity-inbound-auth-oauth\")  object(expression:\"83253ce50f189db30c54f13afa5d99021e2d7ece\")  ... on Commit  blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\")  ranges  startingLine endingLine age commit  message url history(first: 2)  edges  node  message url    author  name email        "' https://api.github.com/graphql

并在 Java 中运行相同的 curl 命令,如下所示

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Demo 
    public static void main(String[] args) 

        String url="https://api.github.com/graphql";
           String[] command = "curl", "-H" ,"Authorization: Bearer myGitHubToken","-H","Accept:application/json","-X", "POST", "-d", "\"query\": \"query  repository(owner: \\\"wso2-extensions\\\", name: \\\"identity-inbound-auth-oauth\\\")  object(expression:\\\"83253ce50f189db30c54f13afa5d99021e2d7ece\\\")  ... on Commit  blame(path: \\\"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\\\")  ranges  startingLine endingLine age commit  message url history(first: 2)  edges  node  message url    author  name email        \"" , url;
            ProcessBuilder process = new ProcessBuilder(command); 
            Process p;
            try
            
                p = process.start();
                 BufferedReader reader =  new BufferedReader(new InputStreamReader(p.getInputStream()));
                    StringBuilder builder = new StringBuilder();
                    String line = null;
                    while ( (line = reader.readLine()) != null) 
                            builder.append(line);
                            builder.append(System.getProperty("line.separator"));
                    
                    String result = builder.toString();
                    System.out.print(result);

            
            catch (IOException e)
               System.out.print("error");
                e.printStackTrace();
            
    


有没有其他方法可以在不运行 curl 命令的情况下在 java 中获得相同的输出,因为在 java 中运行 curl 命令不是一个好习惯(根据我的观点)。提前致谢

使用 httpClient 代码更新

这是我尝试使用apache httpClient 的代码

public void callingGraph()
        CloseableHttpClient client= null;
        CloseableHttpResponse response= null;

        client= HttpClients.createDefault();
        HttpPost httpPost= new HttpPost("https://api.github.com/graphql");

        httpPost.addHeader("Authorization","Bearer myToken");
        httpPost.addHeader("Accept","application/json");


        String temp="repository(owner: \"wso2-extensions\", name: \"identity-inbound-auth-oauth\")  object(expression: \"83253ce50f189db30c54f13afa5d99021e2d7ece\")  ... on Commit  blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\")  ranges  startingLine, endingLine, age, commit  message url history(first: 2)  edges  node   message, url    author  name, email        ";

//        String temp="repository(owner:\"wso2\",name:\"product-is\")description";

        try 

           StringEntity entity= new StringEntity("\"query\":\"query "+temp+"\"");

            httpPost.setEntity(entity);
            response= client.execute(httpPost);

        

        catch(UnsupportedEncodingException e)
            e.printStackTrace();
        
        catch(ClientProtocolException e)
            e.printStackTrace();
        
        catch(IOException e)
            e.printStackTrace();
        

        try
            BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line= null;
            StringBuilder builder= new StringBuilder();
            while((line=reader.readLine())!= null)

                builder.append(line);

            
            System.out.println(builder.toString());
        
        catch(Exception e)
            e.printStackTrace();
        


    

但即使是 repository(owner:\"wso2\",name:\"product-is\")description 的小查询,它也会给我

"message":"解析 JSON 的问题","documentation_url":"https://developer.github.com/v3"

但是当像这样的简单查询通过String temp="viewer email login "; 时,它可以工作。我的代码有什么问题。请帮忙

【问题讨论】:

【参考方案1】:

问题在于您添加了一个额外的“查询”词,应该是 像这样:

(...)
StringEntity entity= new StringEntity("\"query\":\""+temp+"\"");

虽然我应该提醒您,您应该尽可能避免尝试对 json 进行硬编码,因此,理想情况下您应该使用 JSON 库,从而产生类似这样的内容(完整代码):

import org.json.JSONObject; // New import

public void callingGraph()
        CloseableHttpClient client= null;
        CloseableHttpResponse response= null;

        client= HttpClients.createDefault();
        HttpPost httpPost= new HttpPost("https://api.github.com/graphql");

        httpPost.addHeader("Authorization","Bearer myToken");
        httpPost.addHeader("Accept","application/json");

        JSONObject jsonobj = new JSONObject();     
        jsonobj.put("query", "repository(owner: \"wso2-extensions\", name: \"identity-inbound-auth-oauth\")  object(expression: \"83253ce50f189db30c54f13afa5d99021e2d7ece\")  ... on Commit  blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\")  ranges  startingLine, endingLine, age, commit  message url history(first: 2)  edges  node   message, url    author  name, email        ");

        try 
            StringEntity entity= new StringEntity(jsonobj.toString());

            httpPost.setEntity(entity);
            response= client.execute(httpPost);

        

        catch(UnsupportedEncodingException e)
            e.printStackTrace();
        
        catch(ClientProtocolException e)
            e.printStackTrace();
        
        catch(IOException e)
            e.printStackTrace();
        

        try
            BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line= null;
            StringBuilder builder= new StringBuilder();
            while((line=reader.readLine())!= null)

                builder.append(line);

            
            System.out.println(builder.toString());
        
        catch(Exception e)
            e.printStackTrace();
        


    

记下转义的双引号是如何使 java 可以将其理解为单个字符串的。

【讨论】:

【参考方案2】:

@AdrianoMartins 的答案是正确的,但我可以通过简单地修改该行来让我的程序正常工作

String temp="repository(owner: \"wso2-extensions\", name: \"identity-inbound-auth-oauth\")  object(expression: \"83253ce50f189db30c54f13afa5d99021e2d7ece\")  ... on Commit  blame(path: \"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\")  ranges  startingLine, endingLine, age, commit  message url history(first: 2)  edges  node   message, url    author  name, email        ";

String temp="repository(owner: \\\"wso2-extensions\\\", name: \\\"identity-inbound-auth-oauth\\\")  object(expression: \\\"83253ce50f189db30c54f13afa5d99021e2d7ece\\\")  ... on Commit  blame(path: \\\"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\\\")  ranges  startingLine, endingLine, age, commit  message url history(first: 2)  edges  node   message, url    author  name, email        ";

所以整个程序会是这样的

    public void callingGraph()
        CloseableHttpClient client= null;
        CloseableHttpResponse response= null;

        client= HttpClients.createDefault();
        HttpPost httpPost= new HttpPost("https://api.github.com/graphql");

        httpPost.addHeader("Authorization","Bearer myToken");
        httpPost.addHeader("Accept","application/json");


        String temp="repository(owner: \\\"wso2-extensions\\\", name: \\\"identity-inbound-auth-oauth\\\")  object(expression: \\\"83253ce50f189db30c54f13afa5d99021e2d7ece\\\")  ... on Commit  blame(path: \\\"components/org.wso2.carbon.identity.oauth.endpoint/src/main/java/org/wso2/carbon/identity/oauth/endpoint/authz/OAuth2AuthzEndpoint.java\\\")  ranges  startingLine, endingLine, age, commit  message url history(first: 2)  edges  node   message, url    author  name, email        ";

//        String temp="repository(owner:\"wso2\",name:\"product-is\")description";

        try 

           StringEntity entity= new StringEntity("\"query\":\"query "+temp+"\"");

            httpPost.setEntity(entity);
            response= client.execute(httpPost);

        

        catch(UnsupportedEncodingException e)
            e.printStackTrace();
        
        catch(ClientProtocolException e)
            e.printStackTrace();
        
        catch(IOException e)
            e.printStackTrace();
        

        try
            BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            String line= null;
            StringBuilder builder= new StringBuilder();
            while((line=reader.readLine())!= null)

                builder.append(line);

            
            System.out.println(builder.toString());
        
        catch(Exception e)
            e.printStackTrace();
        


    

正如 Adriano Martins 还建议使用 JSON 库比硬编码 JSON 更好

【讨论】:

【参考方案3】:

你也应该添加

responce.close()

这里建议http://hc.apache.org/httpcomponents-client-4.4.x/tutorial/html/fundamentals.html#d5e145

【讨论】:

以上是关于如何从java访问github graphql API而不在java中运行curl命令的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 java 访问 github graphql API

GitHub 的 GraphQL API 如何从 Java 中使用?

Graphql实践使用 Apollo(iOS) 访问 Github 的 Graphql API

如何使用 HttpUrlConnect 使用 java 查询 Github graphql API

Github GraphQL API,硬编码访问令牌有效,试图混淆它没有

Github v4 GraphQL API - 访问 Marketplace 应用结果 (Travis CI)