当前位置: 首页 > 知识库问答 >
问题:

我应该使用HttpURLConnection还是RestTemplate[duplicate]

高山
2023-03-14

我应该在Spring项目中使用HttpURLConnection,还是更好地使用restemplate?换句话说,什么时候使用每种方法更好?

共有1个答案

闾丘京
2023-03-14

HttpURLConnectionrestemplate是不同的类型。它们在不同的抽象级别上运行。

restemplate有助于使用RESTapi,HttpURLConnection与HTTP协议一起工作。

你在问什么更好用。答案取决于你想实现什么:

  • 如果您需要使用RESTapi,请坚持使用RestTemboard
  • 如果您需要使用超文本传输协议,请使用 <罢工> HttpURLConnection 如果你使用的是Java11,你可以试试它的代码。

此外,RestTemboard使用HttpUrlConnection/OkHttpClient/...来完成它的工作(参见ClientHttpRequest estFactorySimpleClientHttpRequest estFactoryOkHttp3ClientHttpRequest estFactory

最好显示一些代码:

在下面的示例中,使用了JSONPlaceholder

让我们GET一个帖子:

public static void main(String[] args) {
  URL url;
  try {
    url = new URL("https://jsonplaceholder.typicode.com/posts/1");
  } catch (MalformedURLException e) {
    // Deal with it.
    throw new RuntimeException(e);
  }
  HttpURLConnection connection = null;
  try {
    connection = (HttpURLConnection) url.openConnection();
    try (InputStream inputStream = connection.getInputStream();
         InputStreamReader isr = new InputStreamReader(inputStream);
         BufferedReader bufferedReader = new BufferedReader(isr)) {
      // Wrap, wrap, wrap

      StringBuilder response = new StringBuilder();
      String line;
      while ((line = bufferedReader.readLine()) != null) {
        response.append(line);
      }
      // Here is the response body
      System.out.println(response.toString());
    }

  } catch (IOException e) {
    throw new RuntimeException(e);
  } finally {
    if (connection != null) {
      connection.disconnect();
    }
  }
}

现在让我们POST发布一些内容:

connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "application/json; charset=UTF-8");

try (OutputStream os = connection.getOutputStream();
     OutputStreamWriter osw = new OutputStreamWriter(os);
     BufferedWriter wr = new BufferedWriter(osw)) {
  wr.write("{\"title\":\"foo\", \"body\": \"bar\", \"userId\": 1}");
}

如果需要响应:

try (InputStream inputStream = connection.getInputStream();
     InputStreamReader isr = new InputStreamReader(inputStream);
     BufferedReader bufferedReader = new BufferedReader(isr)) {
  // Wrap, wrap, wrap

  StringBuilder response = new StringBuilder();
  String line;
  while ((line = bufferedReader.readLine()) != null) {
    response.append(line);
  }

  System.out.println(response.toString());
}

正如您所见,HttpURLConnection提供的api是禁欲主义的。

你总是需要处理“低级”InputStreamReaderOutputStreamWriter,但幸运的是,还有其他选择。

OkHttpClient减少了痛苦:

获取发布帖子:

OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
    .url("https://jsonplaceholder.typicode.com/posts/1")
    .build();
Call call = okHttpClient.newCall(request);
try (Response response = call.execute();
     ResponseBody body = response.body()) {

  String string = body.string();
  System.out.println(string);
} catch (IOException e) {
  throw new RuntimeException(e);
}

POSTing一篇帖子:

Request request = new Request.Builder()
    .post(RequestBody.create(MediaType.parse("application/json; charset=UTF-8"),
        "{\"title\":\"foo\", \"body\": \"bar\", \"userId\": 1}"))
    .url("https://jsonplaceholder.typicode.com/posts")
    .build();

Call call = okHttpClient.newCall(request);

try (Response response = call.execute();
     ResponseBody body = response.body()) {

  String string = body.string();
  System.out.println(string);
} catch (IOException e) {
  throw new RuntimeException(e);
}

容易多了,对吧?

获取帖子:

HttpClient httpClient = HttpClient.newHttpClient();

HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder()
    .uri(URI.create("https://jsonplaceholder.typicode.com/posts/1"))
    .GET()
    .build(), HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

POSTing一篇帖子:

HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder()
    .header("Content-Type", "application/json; charset=UTF-8")
    .uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
    .POST(HttpRequest.BodyPublishers.ofString("{\"title\":\"foo\", \"body\": \"barzz\", \"userId\": 2}"))
    .build(), HttpResponse.BodyHandlers.ofString());

根据其javadoc:

同步客户端执行HTTP请求,在底层HTTP客户端库(例如JDK{@code HttpURLConnection}、Apache HttpComponents等)上公开一个简单的模板方法API。

让我们做同样的事

首先,为了方便起见,创建了Post类。(当restemplate读取响应时,它将使用HttpMessageConverter将其转换为Post

public static class Post {
  public long userId;
  public long id;
  public String title;
  public String body;

  @Override
  public String toString() {
    return new ReflectionToStringBuilder(this)
        .toString();
  }
}

获取一篇帖子。

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Post> entity = restTemplate.getForEntity("https://jsonplaceholder.typicode.com/posts/1", Post.class);
Post post = entity.getBody();
System.out.println(post);

POSTing一篇帖子:

public static class PostRequest {
  public String body;
  public String title;
  public long userId;
}

public static class CreatedPost {
  public String body;
  public String title;
  public long userId;
  public long id;

  @Override
  public String toString() {
    return new ReflectionToStringBuilder(this)
        .toString();
  }
}

public static void main(String[] args) {

  PostRequest postRequest = new PostRequest();
  postRequest.body = "bar";
  postRequest.title = "foo";
  postRequest.userId = 11;


  RestTemplate restTemplate = new RestTemplate();
  CreatedPost createdPost = restTemplate.postForObject("https://jsonplaceholder.typicode.com/posts/", postRequest, CreatedPost.class);
  System.out.println(createdPost);
}

所以回答你的问题:

什么时候最好各用一种?

  • 需要使用RESTapi吗?使用RestTemplate

还值得一提的是:

  • 改装

 类似资料:
  • 问题内容: 我正在使用c / c 为osx和linux开发命令行界面可执行文件。该项目将链接到opencv。我应该使用libc 还是libstdc ++? 问题答案: 我会为每个操作系统使用本机库,即GNU / Linux上的libstdc 和Mac OS X上的libc 。 libc 在GNU / Linux上不是100%完整的,而libstdc 更完整时使用libc并没有真正的优势。另外,如果

  • 问题内容: 和CSS 和有什么不一样?我应该使用哪一个?为什么? 问题答案: 所有这些答案似乎都是不正确的。与直觉相反,在CSS 中不是pixel 。至少不是在简单的物理意义上。 从W3C,EM,PX,PT,CM,IN…阅读本文,了解如何为CSS发明一个“神奇的”单元。的含义因硬件和分辨率而异。(该文章是最新的,最新更新为2014-10。) 我自己的思考方式: px单位是CSS的魔术单位。它与当前

  • 问题内容: 我正在一个将Angular和Underscore都作为依赖项的项目。 当我需要创建对象的副本时,根据当时的心情,我可以使用或 在我看来,这些方法中的一种可能比另一种更快速/可靠/健壮。 假设已经包含两个库,那么这两个函数中的任何一个是否存在使另一个函数更好或更坏使用的已知问题? 问题答案: 关于您的问题: angular.copy和_.clone是不同的。这不是哪个更好的问题,而是关于

  • 问题内容: 我想从文本文件中读取每一行并将它们存储在ArrayList中(每一行是ArrayList中的一项)。 到目前为止,我知道BufferedInputStream写入缓冲区,并且仅在缓冲区为空时才进行另一次读取,这可以最大程度地减少或至少减少操作系统的操作量。 我正确吗-我说得通吗? 如果以上情况是在任何情况下,任何人都想使用DataInputStream。最后,我应该使用这两个中的哪一个

  • 问题内容: 在numpy中,可以使用切片语法中的’newaxis’对象创建长度为1的轴,例如: 该文档的状态是一个也可以用代替,效果是完全一样的。 有什么理由选择一个?是否有一般偏好或样式指南?我的印象是更受欢迎,可能是因为它更明确。那么,有什么理由允许这样做? 问题答案: 之所以被允许,是因为它仅仅是的别名。 作者之所以选择它,是因为他们需要一个方便的常量并且可用。 至于为什么你应该更喜欢过:主

  • 问题内容: 在使用SciPy的和NumPy的一个项目,我应该使用,或? 问题答案: 所以没关系,它们都是相同的值。 这三个模块均提供值的唯一原因是,如果仅使用三个模块之一,则可以方便地访问pi,而无需导入另一个模块。他们没有为pi提供不同的值。