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