我知道有很多方法可以从远程GET
数据。我尝试了这些不同的类型:
curl
或Runtime.getRuntime().exec(...)
中使用new ProcessBuilder(...).start()
; URL
或RestTemplate
; 在使用其中之一之前,我们之间应该考虑一下重要差异吗?
为什么我要问这个看似话题太广或基于意见的问题?
在高度并发的系统中使用ProcessorBuilder
时遇到问题,使用TimeOut
时会有RestTemplate
,没有?!
经过调试和调试,我发现没有任何与结果相关的东西,我问了这个问题以了解我可能忽略的内容。
List<CompletableFuture<GrafanaDashboard>> futureList = dbList.stream()
.map(boardName -> CompletableFuture.supplyAsync(() -> GrafanaRetriever
.parseDashboard(apiUrl, tokenString, boardName), Executors.newCachedThreadPool()))
.collect(Collectors.toList());
for (CompletableFuture<GrafanaDashboard> completableFuture : futureList) {
try {
dashboards.add(completableFuture.get(30, TimeUnit.SECONDS));
// using ProcessorBuilder, it will hang here and some might time out (not all just some)
// using RestTemplate, it will not wait almost, just smooth and no time out at all;
} catch (ExecutionException | InterruptedException | TimeoutException e) {
log.warn("Retrieving data from grafana failed due to TimeOut most likely by {}", apiUrl);
e.printStackTrace();
}
}
这是一个小示例,用于使用http GET
和cookie
来获取所有数据:
public class RunTimeExecTest {
private static String urlString = "https://www.google.com.sg";
private static String tokenString = "your_cookie";
public static void main(String... args) {
getWithRunTimeExec();
getWithProcessorBuilder();
getUsingUrl();
getUsingRestTemplate();
}
private static void getWithRunTimeExec() {
System.out.println("Using RunTime.exec: ");
try {
Process process = Runtime.getRuntime().exec("curl -v --cookie \"" + tokenString + "\" " + urlString);
process.waitFor();
System.out.println(IoHelper.output(process.getInputStream()));
process = Runtime.getRuntime().exec(new String[]{"curl", "-v", "--cookie", tokenString, urlString});
process.waitFor();
System.out.println(IoHelper.output(process.getInputStream()));
} catch (IOException | InterruptedException ignored) {
ignored.printStackTrace();
}
}
private static void getWithProcessorBuilder() {
System.out.println("Using ProcessorBuilder: ");
try {
Process process = new ProcessBuilder("curl", "-v", "--cookie", tokenString, urlString).start();
process.waitFor();
System.out.println(IoHelper.output(process.getInputStream()));
} catch (IOException | InterruptedException ignored) {
ignored.printStackTrace();
}
}
private static void getUsingUrl() {
System.out.println("Using Url: ");
try {
URL myURL = new URL(urlString);
HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
myURLConnection.setRequestMethod("GET");
myURLConnection.setRequestProperty("cookie", tokenString);
myURLConnection.connect();
System.out.println(IoHelper.output(myURLConnection.getInputStream()));
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void getUsingRestTemplate() {
System.out.println("Using RestTemplate: ");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", tokenString);
HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
ResponseEntity rssResponse = restTemplate.exchange(
urlString,
HttpMethod.GET,
requestEntity,
String.class);
System.out.println(rssResponse.getBody());
}
}
我发现的东西:
URL
或RestTemplate
提供的by spring.web
可能会更强大,因为它们提供了合同他们可以做什么和不清楚的事情; URL
或RestTemplate
可以处理使用curl
很难(甚至不可能)完成的一些复杂过程; URL
和RestTemplate
可能会给图书馆维护者留下很多问题,甚至可以把它们留在那里(RestTemplate
不需要try{...} catch(...){...}
; 答案 0 :(得分:2)
使用其余模板(或用于HTTP请求的另一个Java库,甚至Java URL包中的构建)比使用运行时更好。除了以后可能很重要的可移植性,即使您不认为现在需要它也有其他优点。
代码更易于维护和理解(想象一个不了解curl -D -X -H等的开发人员)。调试起来更容易。例如,当您花费太长时间并且更容易进行错误处理时,可以使用某种断路器。您可以在读取结果等过程中对其进行处理。基本上,您拥有控制权,而没有一些外部工具。
使用运行时可能使您不必编写几行代码,但是由于您正在编写Java程序,因此最好以Java方式进行;)
答案 1 :(得分:1)
为了击中GET
,我宁愿使用Java。由于以下原因:
a。卷曲通常在* nix上找到。使用Java,您的代码应该与平台无关。如果将来您的代码需要在Windows上运行。它将具有卷发或潜在代码更改的依赖性。
b。您可以更好地进行错误处理,而不必诉诸于curl的输出或其退出代码。
c。如果需要解析GET API的输出,Spring可以为您提供帮助。