Создание класса-оболочки для команды curl в Java - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь написать класс-оболочку, то есть класс, который будет делать запросы и обрабатывать ответы следующей команды curl в java.

Команда curl:

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

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Я не вижу цели написания обертки для локона. Вы можете использовать существующие классы URL, HttpClient или RestClient.

0 голосов
/ 28 августа 2018

Предположим, что вам необходимо использовать cURL, а не какой-либо из готовых HTTP-клиентов Java, вы можете создать простую оболочку, которая будет использовать 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), но, эй, я полагаю, что это для какого-либо задания, поэтому то, что вам нужно использовать, может быть ограничено с точки зрения опций.

Я пробовал вышеупомянутое только для варианта использования, который вы хотите использовать, но я не понимаю, как это не будет работать и в других случаях.

0 голосов
/ 28 августа 2018

Вы можете использовать ProcessBuilder:
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html

Я использую его в своем классе CommandLineProcess (конструктор выполняет всю работу):

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());
    }
}
...