使用java的Runtime.getRuntime().exec与curl命令配合使用

4

我想在Java程序中使用Runtime.getRuntime().exec来使用curl。

完整的代码片段如下,但是我的问题归结为:当我在Runtime.getRuntime().exec(命令)中使用curl 命令时,我会得到一个错误响应,但是当我将命令 System.out.println出来,复制并粘贴到shell中执行,它就能正常工作。

System.out.println(command);
Runtime.getRuntime().exec(command);

为什么在运行时使用Runtime执行命令和在shell中执行命令会产生不同的结果。

感谢任何提示。

马丁

更新:

  • 当我使用Runtime时,我得到的错误响应是:{"error":"未经授权"}

  • 从命令中可以看出似乎不清楚。我没有遇到任何异常,curl命令运行正常,但json响应与上面发布的相同。


String APP_ID = "XXX";
String REST_API_KEY = "YYY";

String header = "-H \"X-Parse-Application-Id: " + APP_ID
        + "\" -H \"X-Parse-REST-API-Key: " + REST_API_KEY
        + "\" -H \"Content-Type: application/zip\" ";

public void post2Parse(String fileName) {

    String outputString;

    String command = "curl -X POST " + header + "--data-binary '@"
            + fileName + "' https://api.parse.com/1/files/" + fileName;

    System.out.println(command);

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

        DataInputStream curlIn = new DataInputStream(
                curlProc.getInputStream());

        while ((outputString = curlIn.readLine()) != null) {
            System.out.println(outputString);
        }

    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

1
请发布您收到的异常/错误。 - CloudyMarble
{"error":"未授权"} - dorjeduck
你是否收到了异常?它有什么错误代码和信息?还是输出显示未经授权? - CloudyMarble
不要忘记,您创建的任何子进程都将继承其父进程的权限/访问权限。确保Java正在使用任何所需的权限运行。 - MadProgrammer
刚刚执行了Runtime.getRuntime().exec("which curl"),发现它使用的是另一个curl而不是shell中使用的curl - 糟糕的设置。尽管如此,当我使用与shell中相同的完整路径调用curl时,它仍然无法工作。所以,由于我必须继续前进,我做了一些丑陋但有效的事情。我编写了一个执行curl的shell脚本,并从Java中调用该shell脚本,目前这样可以工作... - dorjeduck
显示剩余3条评论
2个回答

4

我没有直接的答案,但说一下情况,撇号会被编码为不同的字符。虽然这是一个旧问题,但我会回答它以供参考,也许有人以后可以解释完整的答案。

当我类似地测试我们的API时,我注意到以下情况:

curl -i http://localhost:8080/auth/login -d 'identifier=test@example.com&password=test'

当从shell发送此命令时,它最终在服务器上呈现为:

identifier=test@example.com,\npassword=test,\n

但当从Runtime.getRuntime().exec(command)发送时,它变成了:

'identifier=test@example.com,\npassword=test',\n

如果我修改curl命令并删除撇号,它会起作用(由于此命令的本质)。
 curl -i http://localhost:8080/auth/login -d identifier=test@example.com&password=test

因此,一个合理的猜测是,如果问题中的代码更改为以下内容,则在文件名不包含空格的情况下可能会实际起作用...:
String command = "curl -X POST " + header + "--data-binary @"
        + fileName + " https://api.parse.com/1/files/" + fileName;

一种选项是使用执行命令并使用输入数组,如此处所述:Runtime Exec seems to be ignoring apostrophes,再结合解析curl命令(除非硬编码),如此处所述:Split string on spaces in Java, except if between quotes (i.e. treat \"hello world\" as one token)


您真是救了我一命,先生。我已经撞了几个小时这堵墙了。我想简单地使用curl从gradle上传一个文件(作为快速实现),但用了比预期更长的时间。干杯! - Larusso
你救了我的命。非常感谢你。 - passerbywhu

0

我猜你从Curl得到了一个错误代码而不是异常,再次检查Curl API,你可能会发现缺少参数,比如“用户”或其他东西。

你可以尝试检查this答案中提到的一些提示。


谢谢 - 是的,这不是一个异常,而是一个错误响应,正如所提到的那样。当在shell中执行时,完全相同的curl命令可以正常工作,因此看起来问题并不在Curl API的那一侧... - dorjeduck
我看到了另一篇帖子,但为了简单起见,我决定像那里的评论建议的那样选择Runtime。 - dorjeduck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接