为 Java 中的 curl 命令创建包装器 class

Creating a wrapper class for a curl command in Java

我正在尝试编写一个包装器 class,它是一个 class,它将在 java 中发出请求并处理以下 curl 命令的响应。

curl 命令是:

curl  -XPOST 'http://sda.tech/earl/api/processQuery' -H 'Content-Type:application/json' -d"{\"nlquery\":\"Who is the president of Russia?\"}"

您可以使用 ProcessBuilder:
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html

我在我的 CommandLineProcess 中使用它 class(构造函数完成所有工作):

private Process p;

public Process getProcess() {
    return p;
}

public
CommandLineProcess
(String[] commandWithParams, String executionDirectory, boolean waitFor)
{
    ProcessBuilder pb = new ProcessBuilder(commandWithParams);
    pb.directory(new File(executionDirectory));

    try {

        p = pb.start();
        if (waitFor) {
            p.waitFor();
        }

    } catch (IOException e) {
        Log.getInstance().error(e.getMessage());
    } catch (InterruptedException e) {
        Log.getInstance().error(e.getMessage());
    }
}

我看不出为 curl 编写包装器的目的。您可以使用现有的 类 URL、HttpClient 或 RestClient。

假设您必须使用 cURL 而不是任何开箱即用的 Java HTTP 客户端,您可以创建一个简单的包装器来使用 Java 的 Process API 调用底层 cURL 可执行文件。

像这样的一个非常简单的客户端会是这样的:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public final class Curl {

    public enum HttpMethod { GET, PUT, POST, DELETE }

    private final String endpoint;
    public String getEndpoint() { return endpoint; }

    private final HttpMethod method;
    public HttpMethod getMethod() { return method; }

    private final String data;
    public String getData() { return data; }

    private final Map<String, String> headers;
    public Map<String, String> getHeaders() { return headers; }

    private Curl(String endpoint, HttpMethod method, String data, Map<String, String> headers) {
    this.endpoint = endpoint;
    this.method = method;
    this.data = data;
    this.headers = headers;
    }

    public String call() throws IOException, InterruptedException {
    List<String> command = new ArrayList<>();

    command.add("curl");
    command.add("-s");
    command.add("-X");
    command.add(method.name());
    command.add("\"" + endpoint + "\"");

    if (headers != null && !headers.isEmpty()) {
        StringBuilder builder = new StringBuilder();
        builder.append("\"");
        headers.keySet().forEach(s -> builder.append(s).append(":").append(headers.get(s)));
        builder.append("\"");
        command.add("-H");
        command.add(builder.toString());
    }

    if (data != null) {
        command.add("-d");
        command.add("\"" + data + "\"");
        command.add(data);
    }

    return doCurl(command.toArray(new String[0]));
    }

    private String doCurl(String[] args) throws IOException, InterruptedException {
        Process process = new ProcessBuilder(args)
        .redirectErrorStream(true)
        .start();

        String lines;
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"))) {
            lines = reader.lines().collect(Collectors.joining("\n"));
    }
    process.waitFor();
        return lines;
    }

    public static class Builder {

        private String endpoint;
        private HttpMethod method;
        private String data;
        private Map<String, String> headers;

        public Builder(String endpoint) {
            this.endpoint = endpoint;
    }

    public Builder method(HttpMethod method) {
            this.method = method;
            return this;
    }

    public Builder data(String data) {
            this.data = data;
            return this;
    }

    public Builder headers(Map<String, String> headers) {
            this.headers = headers;
            return this;
    }

    public Curl create() {
            if (endpoint == null) {
        throw new IllegalArgumentException("Endpoint cannot be null");
        }

        if (method == null) {
            throw new IllegalArgumentException("HTTP method cannot be null");
        }
        return new Curl(endpoint, method, data, headers);
    }

    }

}

然后可以像这样简单地调用端点:

public static void main(String[] args) throws IOException, InterruptedException {

    Map<String, String> map = new HashMap<>();
    map.put("Content-Type", "application/json");
    String data = "{\\"nlquery\\":\\"Who is the president of Russia?\\"}";

        String result = new Curl.Builder("http://sda.tech/earl/api/processQuery")
        .method(Curl.HttpMethod.POST)
        .headers(map)
        .data(data)
        .create()
        .call();


    System.out.println(result);
    }

请注意,正如我之前所说,我不明白您不想使用 Java 组件的原因(例如 Java 9 及更高版本具有本机 HTTP 客户端 https://docs.oracle.com/javase/9/docs/api/jdk/incubator/http/HttpClient.html) 但是嘿,我想这是为了某种作业,所以你需要使用的选项可能会受到限制。

我仅针对您希望使用它的用例尝试了上述方法,但我不明白这对其他情况也不起作用。