哪种方法更好地从远程服务获取数据

时间:2018-08-06 07:44:14

标签: java spring http

我知道有很多方法可以从远程GET数据。我尝试了这些不同的类型:

  1. curlRuntime.getRuntime().exec(...)中使用new ProcessBuilder(...).start()
  2. 将库用作URLRestTemplate

在使用其中之一之前,我们之间应该考虑一下重要差异吗?

更新#0

为什么我要问这个看似话题太广基于意见的问题?

在高度并发的系统中使用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();
        }
    }

更新#1

这是一个小示例,用于使用http GETcookie来获取所有数据:

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

更新#2

我发现的东西:

  1. 使用URLRestTemplate提供的by spring.web可能会更强大,因为它们提供了合同他们可以做什么和不清楚的事情;
  2. 在不同的平台上,您不会回答那些变化很大的特定命令;
  3. 难以维护,因为它要求Java程序员理解的不仅仅是Java;
  4. 使用URLRestTemplate可以处理使用curl很难(甚至不可能)完成的一些复杂过程;
  5. 使用URLRestTemplate可能会给图书馆维护者留下很多问题,甚至可以把它们留在那里(RestTemplate不需要try{...} catch(...){...};

2 个答案:

答案 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可以为您提供帮助。