【问题标题】:Java executing curl command not working on some commandsJava执行curl命令不适用于某些命令
【发布时间】:2022-01-11 14:37:58
【问题描述】:

我正在使用带有 Java 11 的 Spring。

我有一个测试 curl 命令,我可以通过 java 成功调用。

final String cmdGetDocId = "curl -X POST https://postman-echo.com/post --data foo1=bar1&foo2=bar2";
Process process = Runtime.getRuntime().exec(cmdGetDocId);
InputStream inputStream = process.getInputStream();
JSONObject json = convertToJSON(inputStream);

返回的 JSON 符合预期。

如果我使用不同的 curl 并在命令行上执行它,它会按预期成功返回一些 JSON。

curl --location --request GET 'http://xxx.xx.xx.xx:8080/document/details/' --header 'Authorization: Basic xxxxx'

但是,如果我尝试从我的 Java 应用程序调用 curl,它会失败。

String cmdGetDocId = "curl --location --request GET 'http://xxx.xx.xx.xx:8080/document/details/' --header 'Authorization: Basic xxxxx'";
Process process = Runtime.getRuntime().exec(cmdGetDocId);
InputStream inputStream = process.getInputStream();
JSONObject json = convertToJSON(inputStream);

返回的 inputStream 为空。

你知道我做错了什么吗?为什么java方法可以调用测试curl,而不能调用其他GET curl?

【问题讨论】:

  • 尝试将-v 添加到 curl 命令中,以便获得更详细的输出并查看返回的内容。从控制台/终端和从程序中启动命令之间可能存在细微差别。
  • 您是否有可能因为 http 到 https 流量而遇到内部重定向?
  • 一个正在运行的命令有三个流——输入、输出和错误。您的 JSON 很可能会出现在输出流中,如果有错误,它们将出现在错误流中。因此,请检查命令的结果代码,然后检查相应的流以获取更多信息。
  • 您最好使用 HTTP 库直接连接到 URL 并接收 HTTP 响应代码和输出,而不是执行外部命令并尝试从那里捕获输入。使用类似HttpURLConnection
  • 如果有退出码>0那么你可以尝试从错误流中获取错误信息

标签: java curl


【解决方案1】:

我做了一个简单的例子来解释你一些事情:

public class Playground {
    public static void main(String... args) throws IOException, InterruptedException {
        String cmdGetDocId = "curl -XGET 'https://google.com'";
        Process process = Runtime.getRuntime().exec(cmdGetDocId);
        InputStream inputStream = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        System.out.println("output: ");
        Thread.sleep(2000);
        while(process.isAlive()) Thread.sleep(100);
        System.out.println("return value: " + process.exitValue());
        reader.lines().forEach(System.out::println);
        reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
        reader.lines().forEach(System.err::println);
        System.out.println("---");
    }
}

一方面,当您尝试输出时,您必须确保命令实际上已完成。为了确保,我有这个肮脏的while-loop。此外,您还想查看错误输出。

此外,您实际上不想在 Java 程序中使用 cURL。有很多漂亮的图书馆,甚至是裸露的HttpURLConnection

【讨论】:

  • 谢谢,我想我会尝试使用HttpURLConnection,正如您和上面的@JohnXF 所建议的那样。
  • 有很好的博客文章和教程。例如:journaldev.com/7148/… 祝你好运!
  • 我尝试过使用HttpURLConnection,但它并不完美,我一定是做错了什么。见:stackoverflow.com/questions/70245571/…
【解决方案2】:

试试这个,

String command = "curl -X POST https://postman-echo.com/post --data foo1=bar1&foo2=bar2";
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process process = builder.start();

InputStream response = process.getInputStream();

如果有错误,这将包含错误,否则将包含响应。

【讨论】:

    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 2023-03-31
    • 2019-11-21
    • 2017-11-19
    • 2021-09-17
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    相关资源
    最近更新 更多