HttpClient&RestTemplate

本贴最后更新于 1604 天前,其中的信息可能已经时移世改

HttpClient

  • HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,
  • HttpClient 不是一个浏览器。它是一个客户端的 HTTP 通信实现库。HttpClient 的目标是发送和接收 HTTP 报文。HttpClient 不会去缓存内容,执行嵌入在 HTML 页面中的 javascript 代码,猜测内容类型,重新格式化请求/重定向 URI,或者其它和 HTTP 运输无关的功能。
  • 应用场景:
    • 在一个 java 服务器中,访问另一个 java 服务器,获取返回的资源

依赖坐标

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.4</version>
</dependency>

springboot 整合 HttpClient 使用

  • 配置类:

      #The config for HttpClient 
      http.maxTotal=300
      http.defaultMaxPerRoute=50
      http.connectTimeout=1000
      http.connectionRequestTimeout=500
      http.socketTimeout=5000
      http.staleConnectionCheckEnabled=true
    
  • 配置类:

    list = template.getMessageConverters();
    for (HttpMessageConverter? mc : list) {
    if (mc instanceof StringHttpMessageConverter) {
    ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8"));
    }
    }
    return template;
    }

      public Integer getMaxTotal() { 
          return maxTotal; 
      } 
    
      public void setMaxTotal(Integer maxTotal) { 
          this.maxTotal = maxTotal; 
      } 
    
      public Integer getDefaultMaxPerRoute() { 
          return defaultMaxPerRoute; 
      } 
    
      public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) { 
          this.defaultMaxPerRoute = defaultMaxPerRoute; 
      } 
    
      public Integer getConnectTimeout() { 
          return connectTimeout; 
      } 
    
      public void setConnectTimeout(Integer connectTimeout) { 
          this.connectTimeout = connectTimeout; 
      } 
    
      public Integer getConnectionRequestTimeout() { 
          return connectionRequestTimeout; 
      } 
    
      public void setConnectionRequestTimeout(Integer connectionRequestTimeout) { 
          this.connectionRequestTimeout = connectionRequestTimeout; 
      } 
    
      public Integer getSocketTimeout() { 
          return socketTimeout; 
      } 
    
      public void setSocketTimeout(Integer socketTimeout) { 
          this.socketTimeout = socketTimeout; 
      } 
    

    }
    ">

      /** 
       * HttpClient的配置类 
       * 
       */ 
      @Configuration 
      @ConfigurationProperties(prefix = "http", ignoreUnknownFields = true) 
      public class HttpClientConfig { 
    
          private Integer maxTotal;// 最大连接 
    
          private Integer defaultMaxPerRoute;// 每个host的最大连接 
    
          private Integer connectTimeout;// 连接超时时间 
    
          private Integer connectionRequestTimeout;// 请求超时时间 
    
          private Integer socketTimeout;// 响应超时时间 
    
          /** 
           * HttpClient连接池 
           * @return 
           */ 
          @Bean 
          public HttpClientConnectionManager httpClientConnectionManager() { 
              PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); 
              connectionManager.setMaxTotal(maxTotal); 
              connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); 
              return connectionManager; 
          } 
    
          /** 
           * 注册RequestConfig 
           * @return 
           */ 
          @Bean 
          public RequestConfig requestConfig() { 
              return RequestConfig.custom().setConnectTimeout(connectTimeout) 
                  .setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout) 
                  .build(); 
          } 
    
          /** 
           * 注册HttpClient 
           * @param manager 
           * @param config 
           * @return 
           */ 
          @Bean 
          public HttpClient httpClient(HttpClientConnectionManager manager, RequestConfig config) { 
              return HttpClientBuilder.create().setConnectionManager(manager).setDefaultRequestConfig(config) 
                  .build(); 
          } 
         /** 
           * 使用连接池管理连接 
           * @param httpClient 
           * @return 
           */ 
          @Bean 
          public ClientHttpRequestFactory requestFactory(HttpClient httpClient) { 
              return new HttpComponentsClientHttpRequestFactory(httpClient); 
          } 
          /** 
           * 使用HttpClient来初始化一个RestTemplate 
           * @param requestFactory 
           * @return 
           */ 
          @Bean 
          public RestTemplate restTemplate(ClientHttpRequestFactory requestFactory) { 
              RestTemplate template = new RestTemplate(requestFactory); 
    
              List<HttpMessageConverter<?>> list = template.getMessageConverters(); 
              for (HttpMessageConverter<?> mc : list) { 
                  if (mc instanceof StringHttpMessageConverter) { 
                      ((StringHttpMessageConverter) mc).setDefaultCharset(Charset.forName("UTF-8")); 
                  } 
              } 
              return template; 
          } 
    
          public Integer getMaxTotal() { 
              return maxTotal; 
          } 
    
          public void setMaxTotal(Integer maxTotal) { 
              this.maxTotal = maxTotal; 
          } 
    
          public Integer getDefaultMaxPerRoute() { 
              return defaultMaxPerRoute; 
          } 
    
          public void setDefaultMaxPerRoute(Integer defaultMaxPerRoute) { 
              this.defaultMaxPerRoute = defaultMaxPerRoute; 
          } 
    
          public Integer getConnectTimeout() { 
              return connectTimeout; 
          } 
    
          public void setConnectTimeout(Integer connectTimeout) { 
              this.connectTimeout = connectTimeout; 
          } 
    
          public Integer getConnectionRequestTimeout() { 
              return connectionRequestTimeout; 
          } 
    
          public void setConnectionRequestTimeout(Integer connectionRequestTimeout) { 
              this.connectionRequestTimeout = connectionRequestTimeout; 
          } 
    
          public Integer getSocketTimeout() { 
              return socketTimeout; 
          } 
    
          public void setSocketTimeout(Integer socketTimeout) { 
              this.socketTimeout = socketTimeout; 
          } 
      }
    

总结

  • 总结:HttpClient 使用起来 太过繁琐。 一般使用 RestTemplate,更多简洁方便调用。
  • HttpComponents 的作用是模拟浏览器获取网页内容。 就是 HttpClient

RestTemplate

  • 传统情况下在 java 代码里访问 restful 服务,一般使用 Apache 的 HttpClient。不过此种方法使用起来太过繁琐。spring 提供了一种简单便捷的模板类来进行操作,这就是 RestTemplate。

依赖

  • RestTemplate 就是 spring 其下的产品,就在封装在 spring 的依赖中

配置类

@Configuration
public class RestTempConfig {
    /**
     * @return 返回一个RestTemplate对象,注册到spring容器中。
     */
    @Bean
    public RestTemplate getRestTemplate(){
        // 使用HttpClient,支持GZIP
    	RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
        //解决RestTemplate的中文乱码问题
        // 设置中文乱码问题方式一
        restTemplate.getMessageConverters().add(1,new StringHttpMessageConverter(Charset.forName("UTF-8")));
        // 设置中文乱码问题方式二
        //restTemplate.getMessageConverters().set(1,
        //new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 支持中文编码
        return restTemplate;
    }
}

调用方法:

  • 可以调用 RestTemplate 的 get ,post 等..各种请求

  • 代码:

    post(@RequestBody Goods goods){
    ResponseEntitystring response = restTemplate.postForEntity("http://localhost:8090/goods", goods , String.class);
    System.out.println("状态码:"+response.getStatusCode());
    System.out.println("返回信息:"+response.getBody());
    System.out.println("Headers:"+response.getHeaders());
    return response;
    }

    @PutMapping
    public ResponseEntitystring put(@RequestBody Goods goods){
    restTemplate.put("http://localhost:8090/goods", goods , String.class);
    return null;
    }

    @DeleteMapping("/{id}")
    public ResponseEntitystring delete(@PathVariable Integer id){
    restTemplate.delete("http://localhost:8090/goods/"+id);
    return ResponseEntity.ok("删除成功");
    }
    ">

      @Autowired
      private RestTemplate restTemplate;
    
      @GetMapping
      public ResponseEntity<String> get(){
          ResponseEntity<String> response = restTemplate.getForEntity("http://localhost:8090/goods?pageNum=1&pageSize=2&name=&key=", String.class);
          System.out.println("状态码:"+response.getStatusCode());
          System.out.println("返回信息:"+response.getBody());
          System.out.println("Headers:"+response.getHeaders());
          return response;
      }
    
      @PostMapping
      public ResponseEntity<String> post(@RequestBody Goods goods){
          ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8090/goods", goods , String.class);
          System.out.println("状态码:"+response.getStatusCode());
          System.out.println("返回信息:"+response.getBody());
          System.out.println("Headers:"+response.getHeaders());
          return response;
      }
    
      @PutMapping
      public ResponseEntity<String> put(@RequestBody Goods goods){
          restTemplate.put("http://localhost:8090/goods", goods , String.class);
          return null;
      }
    
      @DeleteMapping("/{id}")
      public ResponseEntity<String> delete(@PathVariable Integer id){
          restTemplate.delete("http://localhost:8090/goods/"+id);
          return ResponseEntity.ok("删除成功");
      }
    

两者总结

  • 相同点:
    • 跨操作系统和编程语言的的访问技术
    • 访问另一个服务器请求的技术
  • 不同的:
    • httpClient 是 Apache 的,RestTemplate 是 spring 的
    • RestTemplate 更加简单

RestTemplate 获取天气预报

ResponseEntity<String> response = restTemplate.getForEntity("http://wthrcdn.etouch.cn/weather_mini?city=沭阳", String.class);
System.out.println("状态码:"+response.getStatusCode());
System.out.println("返回信息:"+response.getBody());
System.out.println("Headers:"+response.getHeaders());
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    944 引用 • 1459 回帖 • 17 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...