【问题标题】:Unable to execute CURL command through java Runtime.getRuntime().exec()无法通过 java Runtime.getRuntime().exec() 执行 CURL 命令
【发布时间】:2023-08-31 12:07:01
【问题描述】:

我正在使用 java 执行 curl 命令。

curl -i --user "OAMADMIN_tenant_358922247351079_svc_358922247369079_APPID:Iuj.2swilg5fhv" -H "Content-Type: application/json" -H "Accept: application/json" -H 'X-USER-IDENTITY-DOMAIN-NAME: tenant_358922247351079' -H "X-RESOURCE-IDENTITY-DOMAIN-NAME: tenant_358922247351079" --request GET "https://slc04yre-1.dev.oraclecorp.com:4443/oam/services/rest/11.1.2.0.0/oauth/admin/Clients?name=myMCS_svc_358922247369079_MCS_Client_OAUTHCLIENT"

我想在我的代码中得到这个 curl 命令的输出,但是我的标准输出是空的。

 private static String executeCommand(String command) {
        StringBuffer output = new StringBuffer();

        Process p;
        try {
            p = Runtime.getRuntime().exec(command);

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    p.getInputStream()));
            //p.waitFor();
            String line = "";
            while ((line = reader.readLine()) != null) {
                System.out.println("line="+line);
                output.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return output.toString();

    }

尝试手动执行 curl 命令,它工作正常。 然后我打印了标准错误,可以看到:

   [testng] error line=
   [testng] error line=curl: (6) Couldn't resolve host 'application'
   [testng] error line=
   [testng] error line=curl: (6) Couldn't resolve host 'application'
   [testng] error line=
   [testng] error line=curl: (6) Couldn't resolve host 'tenant_359516638431079''
   [testng] error line=
   [testng] error line=curl: (6) Couldn't resolve host 'tenant_359516638431079"'
   [testng] error line=
   [testng] error line=curl: (1) Unsupported protocol: "https

手动执行 curl 命令时,它工作正常,那为什么不通过 Runtime.getRuntime() 呢?

请推荐!!任何帮助将不胜感激。

【问题讨论】:

  • 我正在构建这样的命令: String cmd = "curl -i --user \"" + appId + ":" + appIdPwd + "\" -H \"Content-Type: application /json\" -H \"Accept: application/json\" " + "-H 'X-USER-IDENTITY-DOMAIN-NAME: " + tenantName + "' -H \"X-RESOURCE-IDENTITY-DOMAIN-NAME : " + tenantName + "\" --request GET \"" + url.substring(0, url.lastIndexOf("/")) + "/oam/services/rest/11.1.2.0.0/oauth/admin/客户?name=" + 客户 + "\"";
  • 为什么要执行外部curl进程?您可以直接在java 中轻松发送和处理任何 http 请求。效率会高很多!参见例如:mkyong.com/java/how-to-send-http-request-getpost-in-java
  • https 请求的另一个示例在这里:*.com/questions/6927427/…

标签: java curl


【解决方案1】:

似乎数据外壳/控制台正在解释/更改字符。例如下面这行:

-H "Content-Type: application/json"

... 似乎被解释为三个不同的参数:

-H Content-Type:application/json 通过 shell/控制台。

尝试使用以下格式将命令字符串分解为一组组件:

exec(String[] cmdarray)

这样,shell/控制台将清楚哪些参数组合在一起。

这是一个证明这一点的 groovy 测试:

def Object executeCommand(command) {

   def proc = Runtime.getRuntime().exec(command);
   def sout = new StringBuffer()
   def serr = new StringBuffer()

   proc.consumeProcessOutput(sout, serr)
   proc.waitFor()

   return [ 'sout':sout.toString(), 'serr':serr.toString() ]
}   

response = executeCommand('''curl --silent --show-error -H "Accept: application/json" --request GET "https://education.cloudant.com/"''')
assert response['sout'] == ''
assert response['serr'].startsWith( 'curl: (6) Could not resolve host: application' )

response = executeCommand(['curl', '--silent',  '--show-error',  '-H', 'Accept: application/json',  '--request', 'GET', 'https://education.cloudant.com/'] as String[] )
assert response['sout'].startsWith('{"couchdb":"Welcome","version":"1.0.2","cloudant_build":"2367"}')
assert response['serr'] == ''

【讨论】:

  • 非常感谢克里斯。我尝试将 curl 命令分解为一个数组并且它有效。谢谢!!
  • @Sammi 你能提供有效的代码吗?我也有类似的问题。